Add better namespaces to make documentation easier to handle
This commit is contained in:
parent
eee5c19b6e
commit
0b97fcb4df
@ -9,61 +9,63 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace threading
|
namespace detail
|
||||||
{
|
{
|
||||||
|
namespace threading
|
||||||
|
{
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Thread_Storage
|
class Thread_Storage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~Thread_Storage()
|
~Thread_Storage()
|
||||||
{
|
|
||||||
m_thread_storage.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T *operator->() const
|
|
||||||
{
|
|
||||||
if (!m_thread_storage.get())
|
|
||||||
{
|
{
|
||||||
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 m_thread_storage.get();
|
||||||
{
|
}
|
||||||
return *(this->operator->());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
inline T &operator*() const
|
||||||
mutable boost::thread_specific_ptr<T> m_thread_storage;
|
{
|
||||||
};
|
return *(this->operator->());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable boost::thread_specific_ptr<T> m_thread_storage;
|
||||||
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Thread_Storage
|
class Thread_Storage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline T *operator->() const
|
inline T *operator->() const
|
||||||
{
|
{
|
||||||
return &obj;
|
return &obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T &operator*() const
|
inline T &operator*() const
|
||||||
{
|
{
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable T obj;
|
mutable T obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,43 +11,45 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
|
namespace exception
|
||||||
/**
|
|
||||||
* 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,
|
* class that is thrown in the event of a bad_boxed_cast. That is,
|
||||||
const std::string &what)
|
* in the case that a Boxed_Value cannot be cast to the desired type
|
||||||
: from(t_from), to(&t_to), m_what(what)
|
*/
|
||||||
{
|
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()
|
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")
|
: from(t_from), to(&t_to), m_what("Cannot perform boxed_cast")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_cast(const std::string &w) throw()
|
bad_boxed_cast(const std::string &w) throw()
|
||||||
: m_what(w)
|
: m_what(w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~bad_boxed_cast() throw() {}
|
virtual ~bad_boxed_cast() throw() {}
|
||||||
|
|
||||||
virtual const char * what() const throw()
|
virtual const char * what() const throw()
|
||||||
{
|
{
|
||||||
return m_what.c_str();
|
return m_what.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
Type_Info from;
|
Type_Info from;
|
||||||
const std::type_info *to;
|
const std::type_info *to;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_what;
|
std::string m_what;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,34 +30,38 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename Ret, typename O, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
namespace detail
|
||||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
|
{
|
||||||
|
template<typename Ret, typename O, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
|
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
|
||||||
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const O &o)
|
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, _));
|
return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename O, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
template<typename Ret, typename O, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
|
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
|
||||||
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const, const O &o)
|
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, _));
|
return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
|
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
|
||||||
boost::function<Ret (BOOST_PP_ENUM(n, param, Param))>
|
boost::function<Ret (BOOST_PP_ENUM(n, param, Param))>
|
||||||
bind_first(Ret (*f)(BOOST_PP_ENUM_PARAMS(m, Param)), const O &o)
|
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, _));
|
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
|
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
|
||||||
boost::function<Ret (BOOST_PP_ENUM(n, param, Param))>
|
boost::function<Ret (BOOST_PP_ENUM(n, param, Param))>
|
||||||
bind_first(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(m, Param))> &f, const O &o)
|
bind_first(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(m, Param))> &f, const O &o)
|
||||||
{
|
{
|
||||||
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
|
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef n
|
#undef n
|
||||||
|
@ -58,7 +58,7 @@ namespace chaiscript
|
|||||||
return p1 &= P1(r.i);
|
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<typename P1>
|
template<typename P1>
|
||||||
@ -69,7 +69,7 @@ namespace chaiscript
|
|||||||
return p1 ^= P1(r.i);
|
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<typename P1>
|
template<typename P1>
|
||||||
@ -80,7 +80,7 @@ namespace chaiscript
|
|||||||
return p1 |= P1(r.i);
|
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<typename P1>
|
template<typename P1>
|
||||||
@ -102,7 +102,7 @@ namespace chaiscript
|
|||||||
return p1 <<= P1(r.i);
|
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);
|
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);
|
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));
|
lhs.assign(Boxed_Value(rhs));
|
||||||
return lhs;
|
return lhs;
|
||||||
} else {
|
} 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));
|
return (lhs.assign(rhs));
|
||||||
} else {
|
} 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)
|
if (params.size() < 2)
|
||||||
{
|
{
|
||||||
throw arity_error(static_cast<int>(params.size()), 2);
|
throw exception::arity_error(static_cast<int>(params.size()), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
|
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
|
||||||
@ -470,7 +470,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
if (params.size() < 1)
|
if (params.size() < 1)
|
||||||
{
|
{
|
||||||
throw arity_error(static_cast<int>(params.size()), 1);
|
throw exception::arity_error(static_cast<int>(params.size()), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
|
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
|
||||||
|
@ -20,503 +20,511 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace bootstrap
|
namespace bootstrap
|
||||||
{
|
{
|
||||||
/**
|
namespace standard_library
|
||||||
* 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<typename Container>
|
|
||||||
struct Bidir_Range
|
|
||||||
{
|
{
|
||||||
typedef Container container_type;
|
/**
|
||||||
typedef typename std::iterator_traits<typename Container::iterator>::reference reference_type;
|
* Bidir_Range, based on the D concept of ranges.
|
||||||
|
* \todo Update the Range code to base its capabilities on
|
||||||
Bidir_Range(Container &c)
|
* the user_typetraits of the iterator passed in
|
||||||
: m_begin(c.begin()), m_end(c.end())
|
*/
|
||||||
{
|
template<typename Container>
|
||||||
}
|
struct Bidir_Range
|
||||||
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return m_begin == m_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_front()
|
|
||||||
{
|
|
||||||
if (empty())
|
|
||||||
{
|
{
|
||||||
throw std::range_error("Range empty");
|
typedef Container container_type;
|
||||||
}
|
typedef typename std::iterator_traits<typename Container::iterator>::reference reference_type;
|
||||||
++m_begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back()
|
Bidir_Range(Container &c)
|
||||||
{
|
: m_begin(c.begin()), m_end(c.end())
|
||||||
if (empty())
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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<typename Container>
|
||||||
|
struct Const_Bidir_Range
|
||||||
{
|
{
|
||||||
throw std::range_error("Range empty");
|
typedef const Container container_type;
|
||||||
}
|
typedef typename std::iterator_traits<typename Container::const_iterator>::reference const_reference_type;
|
||||||
--m_end;
|
|
||||||
|
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<typename Bidir_Type>
|
||||||
|
ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(user_type<Bidir_Type>(), type + "_Range");
|
||||||
|
|
||||||
|
copy_constructor<Bidir_Type>(type + "_Range", m);
|
||||||
|
|
||||||
|
m->add(constructor<Bidir_Type (typename Bidir_Type::container_type &)>(), "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<typename Type>
|
||||||
|
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<typename Type>
|
||||||
|
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
|
template<typename ContainerType>
|
||||||
{
|
ModulePtr input_range_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
if (empty())
|
|
||||||
{
|
{
|
||||||
throw std::range_error("Range empty");
|
detail::input_range_type_impl<Bidir_Range<ContainerType> >(type,m);
|
||||||
|
detail::input_range_type_impl<Const_Bidir_Range<ContainerType> >("Const_" + type, m);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
return *m_begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference_type back() const
|
/**
|
||||||
{
|
* Add random_access_container concept to the given ContainerType
|
||||||
if (empty())
|
* http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
||||||
|
*/
|
||||||
|
template<typename ContainerType>
|
||||||
|
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<typename ContainerType::reference (ContainerType *, int)>
|
||||||
|
(boost::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]");
|
||||||
|
m->add(
|
||||||
|
fun(boost::function<typename ContainerType::const_reference (const ContainerType *, int)>
|
||||||
|
(boost::mem_fn(static_cast<constindexoper>(&ContainerType::at)))), "[]");
|
||||||
|
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
typename Container::iterator pos = m_end;
|
|
||||||
--pos;
|
|
||||||
return *(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
typename Container::iterator m_begin;
|
/**
|
||||||
typename Container::iterator m_end;
|
* Add assignable concept to the given ContainerType
|
||||||
};
|
* http://www.sgi.com/tech/stl/Assignable.html
|
||||||
|
*/
|
||||||
template<typename Container>
|
template<typename ContainerType>
|
||||||
struct Const_Bidir_Range
|
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
|
||||||
typedef const Container container_type;
|
|
||||||
typedef typename std::iterator_traits<typename Container::const_iterator>::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");
|
basic_constructors<ContainerType>(type, m);
|
||||||
|
operators::assign<ContainerType>(m);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
++m_begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back()
|
/**
|
||||||
{
|
* Add container concept to the given ContainerType
|
||||||
if (empty())
|
* http://www.sgi.com/tech/stl/Container.html
|
||||||
|
*/
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
throw std::range_error("Range empty");
|
m->add(fun(boost::function<int (const ContainerType *)>(boost::mem_fn(&ContainerType::size))), "size");
|
||||||
}
|
m->add(fun<bool (ContainerType::*)() const>(&ContainerType::empty), "empty");
|
||||||
--m_end;
|
m->add(fun<void (ContainerType::*)()>(&ContainerType::clear), "clear");
|
||||||
}
|
|
||||||
|
|
||||||
const_reference_type front() const
|
return m;
|
||||||
{
|
}
|
||||||
if (empty())
|
|
||||||
|
/**
|
||||||
|
* Add default constructable concept to the given Type
|
||||||
|
* http://www.sgi.com/tech/stl/DefaultConstructible.html
|
||||||
|
*/
|
||||||
|
template<typename Type>
|
||||||
|
ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
throw std::range_error("Range empty");
|
m->add(constructor<Type ()>(), 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<typename ContainerType>
|
||||||
|
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<ContainerType>), insert_name);
|
||||||
|
m->add(fun(&detail::erase_at<ContainerType>), "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<typename ContainerType>
|
||||||
|
ModulePtr back_insertion_sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
typedef typename ContainerType::reference (ContainerType::*backptr)();
|
||||||
|
|
||||||
namespace detail {
|
m->add(fun(static_cast<backptr>(&ContainerType::back)), "back");
|
||||||
/**
|
|
||||||
* Add Bidir_Range support for the given ContainerType
|
|
||||||
*/
|
|
||||||
template<typename Bidir_Type>
|
|
||||||
ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(user_type<Bidir_Type>(), type + "_Range");
|
|
||||||
|
|
||||||
copy_constructor<Bidir_Type>(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<Bidir_Type (typename Bidir_Type::container_type &)>(), "range");
|
typedef void (ContainerType::*pushback)(const typename ContainerType::value_type &);
|
||||||
|
m->add(fun(static_cast<pushback>(&ContainerType::push_back)), push_back_name);
|
||||||
m->add(fun(&Bidir_Type::empty), "empty");
|
m->add(fun(&ContainerType::pop_back), "pop_back");
|
||||||
m->add(fun(&Bidir_Type::pop_front), "pop_front");
|
return m;
|
||||||
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<typename ContainerType>
|
|
||||||
ModulePtr input_range_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
detail::input_range_type_impl<Bidir_Range<ContainerType> >(type,m);
|
|
||||||
detail::input_range_type_impl<Const_Bidir_Range<ContainerType> >("Const_" + type, m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add random_access_container concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
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<typename ContainerType::reference (ContainerType *, int)>(boost::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]");
|
|
||||||
m->add(
|
|
||||||
fun(boost::function<typename ContainerType::const_reference (const ContainerType *, int)>(boost::mem_fn(static_cast<constindexoper>(&ContainerType::at)))), "[]");
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add assignable concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/Assignable.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
basic_constructors<ContainerType>(type, m);
|
|
||||||
operators::assign<ContainerType>(m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add container concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/Container.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(boost::function<int (const ContainerType *)>(boost::mem_fn(&ContainerType::size))), "size");
|
|
||||||
m->add(fun<bool (ContainerType::*)() const>(&ContainerType::empty), "empty");
|
|
||||||
m->add(fun<void (ContainerType::*)()>(&ContainerType::clear), "clear");
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add default constructable concept to the given Type
|
|
||||||
* http://www.sgi.com/tech/stl/DefaultConstructible.html
|
|
||||||
*/
|
|
||||||
template<typename Type>
|
|
||||||
ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(constructor<Type ()>(), type);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Algorithm for inserting at a specific position into a container
|
|
||||||
*/
|
|
||||||
template<typename Type>
|
|
||||||
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<typename Type>
|
|
||||||
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<typename ContainerType>
|
|
||||||
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<ContainerType>), insert_name);
|
|
||||||
m->add(fun(&erase_at<ContainerType>), "erase_at");
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add back insertion sequence concept to the given ContainerType
|
|
||||||
* http://www.sgi.com/tech/stl/BackInsertionSequence.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
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<backptr>(&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<pushback>(&ContainerType::push_back)), push_back_name);
|
|
||||||
m->add(fun(&ContainerType::pop_back), "pop_back");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Front insertion sequence
|
*Front insertion sequence
|
||||||
*http://www.sgi.com/tech/stl/FrontInsertionSequence.html
|
*http://www.sgi.com/tech/stl/FrontInsertionSequence.html
|
||||||
*/
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr front_insertion_sequence_type(const std::string &, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr front_insertion_sequence_type(const std::string &, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
typedef typename ContainerType::reference (ContainerType::*frontptr)();
|
typedef typename ContainerType::reference (ContainerType::*frontptr)();
|
||||||
typedef void (ContainerType::*pushptr)(typename ContainerType::const_reference);
|
typedef void (ContainerType::*pushptr)(typename ContainerType::const_reference);
|
||||||
typedef void (ContainerType::*popptr)();
|
typedef void (ContainerType::*popptr)();
|
||||||
|
|
||||||
m->add(fun(static_cast<frontptr>(&ContainerType::front)), "front");
|
m->add(fun(static_cast<frontptr>(&ContainerType::front)), "front");
|
||||||
|
|
||||||
std::string push_front_name;
|
std::string push_front_name;
|
||||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value))
|
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value))
|
||||||
{
|
{
|
||||||
push_front_name = "push_front_ref";
|
push_front_name = "push_front_ref";
|
||||||
} else {
|
} else {
|
||||||
push_front_name = "push_front";
|
push_front_name = "push_front";
|
||||||
}
|
}
|
||||||
|
|
||||||
m->add(fun(static_cast<pushptr>(&ContainerType::push_front)), push_front_name);
|
|
||||||
m->add(fun(static_cast<popptr>(&ContainerType::pop_front)), "pop_front");
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
m->add(fun(static_cast<pushptr>(&ContainerType::push_front)), push_front_name);
|
||||||
* bootstrap a given PairType
|
m->add(fun(static_cast<popptr>(&ContainerType::pop_front)), "pop_front");
|
||||||
* http://www.sgi.com/tech/stl/pair.html
|
return m;
|
||||||
*/
|
}
|
||||||
template<typename PairType>
|
|
||||||
ModulePtr pair_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(user_type<PairType>(), type);
|
|
||||||
|
|
||||||
|
/**
|
||||||
typename PairType::first_type PairType::* f = &PairType::first;
|
* bootstrap a given PairType
|
||||||
typename PairType::second_type PairType::* s = &PairType::second;
|
* http://www.sgi.com/tech/stl/pair.html
|
||||||
|
*/
|
||||||
m->add(fun(f), "first");
|
template<typename PairType>
|
||||||
m->add(fun(s), "second");
|
ModulePtr pair_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
basic_constructors<PairType>(type, m);
|
m->add(user_type<PairType>(), type);
|
||||||
m->add(constructor<PairType (const typename PairType::first_type &, const typename PairType::second_type &)>(), type);
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
typename PairType::first_type PairType::* f = &PairType::first;
|
||||||
* Add pair associative container concept to the given ContainerType
|
typename PairType::second_type PairType::* s = &PairType::second;
|
||||||
* http://www.sgi.com/tech/stl/PairAssociativeContainer.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
pair_type<typename ContainerType::value_type>(type + "_Pair", m);
|
|
||||||
|
|
||||||
return m;
|
m->add(fun(f), "first");
|
||||||
}
|
m->add(fun(s), "second");
|
||||||
|
|
||||||
/**
|
basic_constructors<PairType>(type, m);
|
||||||
* Add unique associative container concept to the given ContainerType
|
m->add(constructor<PairType (const typename PairType::first_type &, const typename PairType::second_type &)>(), type);
|
||||||
* http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
|
||||||
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(fun(boost::function<int (const ContainerType *, const typename ContainerType::key_type &)>(boost::mem_fn(&ContainerType::count))), "count");
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a MapType container
|
|
||||||
* http://www.sgi.com/tech/stl/Map.html
|
|
||||||
*/
|
|
||||||
template<typename MapType>
|
|
||||||
ModulePtr map_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(user_type<MapType>(), type);
|
|
||||||
|
|
||||||
typedef typename MapType::mapped_type &(MapType::*elemaccess)(const typename MapType::key_type &);
|
|
||||||
|
|
||||||
m->add(fun(static_cast<elemaccess>(&MapType::operator[])), "[]");
|
|
||||||
|
|
||||||
container_type<MapType>(type, m);
|
|
||||||
assignable_type<MapType>(type, m);
|
|
||||||
unique_associative_container_type<MapType>(type, m);
|
|
||||||
pair_associative_container_type<MapType>(type, m);
|
|
||||||
input_range_type<MapType>(type, m);
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hopefully working List type
|
|
||||||
* http://www.sgi.com/tech/stl/List.html
|
|
||||||
*/
|
|
||||||
template<typename ListType>
|
|
||||||
ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(user_type<ListType>(), type);
|
|
||||||
|
|
||||||
front_insertion_sequence_type<ListType>(type, m);
|
|
||||||
back_insertion_sequence_type<ListType>(type, m);
|
|
||||||
sequence_type<ListType>(type, m);
|
|
||||||
container_type<ListType>(type, m);
|
|
||||||
default_constructible_type<ListType>(type, m);
|
|
||||||
assignable_type<ListType>(type, m);
|
|
||||||
input_range_type<ListType>(type, m);
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a vector type with associated concepts
|
|
||||||
* http://www.sgi.com/tech/stl/Vector.html
|
|
||||||
*/
|
|
||||||
template<typename VectorType>
|
|
||||||
ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
|
||||||
{
|
|
||||||
m->add(user_type<VectorType>(), type);
|
|
||||||
|
|
||||||
typedef typename VectorType::reference (VectorType::*frontptr)();
|
|
||||||
m->add(fun(static_cast<frontptr>(&VectorType::front)), "front");
|
|
||||||
|
|
||||||
|
|
||||||
back_insertion_sequence_type<VectorType>(type, m);
|
/**
|
||||||
sequence_type<VectorType>(type, m);
|
* Add pair associative container concept to the given ContainerType
|
||||||
random_access_container_type<VectorType>(type, m);
|
* http://www.sgi.com/tech/stl/PairAssociativeContainer.html
|
||||||
container_type<VectorType>(type, m);
|
*/
|
||||||
default_constructible_type<VectorType>(type, m);
|
template<typename ContainerType>
|
||||||
assignable_type<VectorType>(type, m);
|
ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
input_range_type<VectorType>(type, m);
|
{
|
||||||
|
pair_type<typename ContainerType::value_type>(type + "_Pair", m);
|
||||||
|
|
||||||
if (typeid(VectorType) == typeid(std::vector<Boxed_Value>))
|
return m;
|
||||||
{
|
}
|
||||||
m->eval("def Vector::`==`(rhs) : type_match(rhs, this) { \
|
|
||||||
if ( rhs.size() != this.size() ) { \
|
/**
|
||||||
return false; \
|
* Add unique associative container concept to the given ContainerType
|
||||||
} else { \
|
* http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
||||||
var r1 = range(this); \
|
*/
|
||||||
var r2 = range(rhs); \
|
template<typename ContainerType>
|
||||||
while (!r1.empty()) \
|
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{ \
|
{
|
||||||
if (!eq(r1.front(), r2.front())) \
|
m->add(fun(boost::function<int (const ContainerType *, const typename ContainerType::key_type &)>(boost::mem_fn(&ContainerType::count))), "count");
|
||||||
{ \
|
|
||||||
return false; \
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a MapType container
|
||||||
|
* http://www.sgi.com/tech/stl/Map.html
|
||||||
|
*/
|
||||||
|
template<typename MapType>
|
||||||
|
ModulePtr map_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(user_type<MapType>(), type);
|
||||||
|
|
||||||
|
typedef typename MapType::mapped_type &(MapType::*elemaccess)(const typename MapType::key_type &);
|
||||||
|
|
||||||
|
m->add(fun(static_cast<elemaccess>(&MapType::operator[])), "[]");
|
||||||
|
|
||||||
|
container_type<MapType>(type, m);
|
||||||
|
assignable_type<MapType>(type, m);
|
||||||
|
unique_associative_container_type<MapType>(type, m);
|
||||||
|
pair_associative_container_type<MapType>(type, m);
|
||||||
|
input_range_type<MapType>(type, m);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hopefully working List type
|
||||||
|
* http://www.sgi.com/tech/stl/List.html
|
||||||
|
*/
|
||||||
|
template<typename ListType>
|
||||||
|
ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(user_type<ListType>(), type);
|
||||||
|
|
||||||
|
front_insertion_sequence_type<ListType>(type, m);
|
||||||
|
back_insertion_sequence_type<ListType>(type, m);
|
||||||
|
sequence_type<ListType>(type, m);
|
||||||
|
container_type<ListType>(type, m);
|
||||||
|
default_constructible_type<ListType>(type, m);
|
||||||
|
assignable_type<ListType>(type, m);
|
||||||
|
input_range_type<ListType>(type, m);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a vector type with associated concepts
|
||||||
|
* http://www.sgi.com/tech/stl/Vector.html
|
||||||
|
*/
|
||||||
|
template<typename VectorType>
|
||||||
|
ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
|
{
|
||||||
|
m->add(user_type<VectorType>(), type);
|
||||||
|
|
||||||
|
typedef typename VectorType::reference (VectorType::*frontptr)();
|
||||||
|
m->add(fun(static_cast<frontptr>(&VectorType::front)), "front");
|
||||||
|
|
||||||
|
|
||||||
|
back_insertion_sequence_type<VectorType>(type, m);
|
||||||
|
sequence_type<VectorType>(type, m);
|
||||||
|
random_access_container_type<VectorType>(type, m);
|
||||||
|
container_type<VectorType>(type, m);
|
||||||
|
default_constructible_type<VectorType>(type, m);
|
||||||
|
assignable_type<VectorType>(type, m);
|
||||||
|
input_range_type<VectorType>(type, m);
|
||||||
|
|
||||||
|
if (typeid(VectorType) == typeid(std::vector<Boxed_Value>))
|
||||||
|
{
|
||||||
|
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
|
* Add a String container
|
||||||
* http://www.sgi.com/tech/stl/basic_string.html
|
* http://www.sgi.com/tech/stl/basic_string.html
|
||||||
*/
|
*/
|
||||||
template<typename String>
|
template<typename String>
|
||||||
ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(user_type<String>(), type);
|
m->add(user_type<String>(), type);
|
||||||
operators::addition<String>(m);
|
operators::addition<String>(m);
|
||||||
operators::assign_sum<String>(m);
|
operators::assign_sum<String>(m);
|
||||||
opers_comparison<String>(m);
|
opers_comparison<String>(m);
|
||||||
random_access_container_type<String>(type, m);
|
random_access_container_type<String>(type, m);
|
||||||
sequence_type<String>(type, m);
|
sequence_type<String>(type, m);
|
||||||
default_constructible_type<String>(type, m);
|
default_constructible_type<String>(type, m);
|
||||||
container_type<String>(type, m);
|
container_type<String>(type, m);
|
||||||
assignable_type<String>(type, m);
|
assignable_type<String>(type, m);
|
||||||
input_range_type<String>(type, m);
|
input_range_type<String>(type, m);
|
||||||
|
|
||||||
//Special case: add push_back to string (which doesn't support other back_insertion operations
|
//Special case: add push_back to string (which doesn't support other back_insertion operations
|
||||||
std::string push_back_name;
|
std::string push_back_name;
|
||||||
if (typeid(typename String::value_type) == typeid(Boxed_Value))
|
if (typeid(typename String::value_type) == typeid(Boxed_Value))
|
||||||
{
|
{
|
||||||
push_back_name = "push_back_ref";
|
push_back_name = "push_back_ref";
|
||||||
} else {
|
} else {
|
||||||
push_back_name = "push_back";
|
push_back_name = "push_back";
|
||||||
}
|
}
|
||||||
m->add(fun(&String::push_back), push_back_name);
|
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<int (const String *, const String &, int)> find_func;
|
typedef boost::function<int (const String *, const String &, int)> find_func;
|
||||||
|
|
||||||
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find)))), "find");
|
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find)))), "find");
|
||||||
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::rfind)))), "rfind");
|
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::rfind)))), "rfind");
|
||||||
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_first_of)))), "find_first_of");
|
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_first_of)))), "find_first_of");
|
||||||
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_last_of)))), "find_last_of");
|
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_last_of)))), "find_last_of");
|
||||||
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_first_not_of)))), "find_first_not_of");
|
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_first_not_of)))), "find_first_not_of");
|
||||||
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_last_not_of)))), "find_last_not_of");
|
m->add(fun(find_func(boost::mem_fn(static_cast<find_func_ptr>(&String::find_last_not_of)))), "find_last_not_of");
|
||||||
|
|
||||||
m->add(fun(&String::c_str), "c_str");
|
m->add(fun(&String::c_str), "c_str");
|
||||||
m->add(fun(&String::data), "data");
|
m->add(fun(&String::data), "data");
|
||||||
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,19 +44,19 @@ namespace chaiscript
|
|||||||
#pragma warning(disable : 4127)
|
#pragma warning(disable : 4127)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (boost::is_polymorphic<typename Stripped_Type<Type>::type>::value)
|
if (boost::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
|
// 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
|
// either way, we are not responsible if it doesn't work
|
||||||
return detail::Cast_Helper<Type>::cast(boxed_dynamic_cast<Type>(bv));
|
return detail::Cast_Helper<Type>::cast(boxed_dynamic_cast<Type>(bv));
|
||||||
} catch (const boost::bad_any_cast &) {
|
} 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 {
|
} else {
|
||||||
// If it's not polymorphic, just throw the error, don't waste the time on the
|
// If it's not polymorphic, just throw the error, don't waste the time on the
|
||||||
// attempted dynamic_cast
|
// 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
|
#ifdef BOOST_MSVC
|
||||||
|
@ -128,7 +128,7 @@ namespace chaiscript
|
|||||||
return Boxed_Value(i & r.i);
|
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
|
Boxed_Value operator^(const Boxed_POD_Value &r) const
|
||||||
@ -138,7 +138,7 @@ namespace chaiscript
|
|||||||
return Boxed_Value(i ^ r.i);
|
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
|
Boxed_Value operator|(const Boxed_POD_Value &r) const
|
||||||
@ -148,7 +148,7 @@ namespace chaiscript
|
|||||||
return Boxed_Value(i | r.i);
|
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
|
Boxed_Value operator/(const Boxed_POD_Value &r) const
|
||||||
@ -168,7 +168,7 @@ namespace chaiscript
|
|||||||
return smart_size(i << r.i);
|
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);
|
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
|
Boxed_Value operator>>(const Boxed_POD_Value &r) const
|
||||||
@ -200,7 +200,7 @@ namespace chaiscript
|
|||||||
return smart_size(i >> r.i);
|
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
|
Boxed_Value smart_size(boost::int64_t i) const
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
|
|
||||||
#include "../chaiscript_threading.hpp"
|
#include "../chaiscript_threading.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/any.hpp>
|
#include <boost/any.hpp>
|
||||||
@ -273,30 +274,40 @@ namespace chaiscript
|
|||||||
boost::shared_ptr<Data> m_data;
|
boost::shared_ptr<Data> 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<typename T>
|
template<typename T>
|
||||||
Boxed_Value var(T t)
|
Boxed_Value var(T t)
|
||||||
{
|
{
|
||||||
return Boxed_Value(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<typename T>
|
template<typename T>
|
||||||
Boxed_Value const_var(T *t)
|
Boxed_Value const_var(T *t)
|
||||||
{
|
{
|
||||||
return Boxed_Value( const_cast<typename boost::add_const<T>::type *>(t) );
|
return Boxed_Value( const_cast<typename boost::add_const<T>::type *>(t) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// boost::shared_ptr<T> overload for const_var
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Boxed_Value const_var(const boost::shared_ptr<T> &t)
|
Boxed_Value const_var(const boost::shared_ptr<T> &t)
|
||||||
{
|
{
|
||||||
return Boxed_Value( boost::const_pointer_cast<typename boost::add_const<T>::type>(t) );
|
return Boxed_Value( boost::const_pointer_cast<typename boost::add_const<T>::type>(t) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// boost::reference_wrapper<T> overload for const_var
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Boxed_Value const_var(const boost::reference_wrapper<T> &t)
|
Boxed_Value const_var(const boost::reference_wrapper<T> &t)
|
||||||
{
|
{
|
||||||
return Boxed_Value( boost::cref(t.get()) );
|
return Boxed_Value( boost::cref(t.get()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generic overload for const_var
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Boxed_Value const_var(const T &t)
|
Boxed_Value const_var(const T &t)
|
||||||
{
|
{
|
||||||
|
@ -970,7 +970,7 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Dynamic_Cast_Conversion> m_conversions;
|
std::vector<Dynamic_Cast_Conversion> m_conversions;
|
||||||
chaiscript::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
chaiscript::detail::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
||||||
|
|
||||||
|
|
||||||
State m_state;
|
State m_state;
|
||||||
|
@ -15,26 +15,28 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
class bad_boxed_dynamic_cast : public bad_boxed_cast
|
namespace exception
|
||||||
{
|
{
|
||||||
public:
|
class bad_boxed_dynamic_cast : public bad_boxed_cast
|
||||||
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
|
{
|
||||||
const std::string &t_what)
|
public:
|
||||||
: bad_boxed_cast(t_from, t_to, t_what)
|
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_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) throw()
|
||||||
: bad_boxed_cast(t_from, t_to)
|
: 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 std::string &w) throw()
|
||||||
|
: bad_boxed_cast(w)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
@ -114,9 +116,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
try {
|
||||||
return detail::Dynamic_Conversions::get().get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
|
return detail::Dynamic_Conversions::get().get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
|
||||||
} catch (const std::out_of_range &) {
|
} 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 &) {
|
} 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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,239 +34,242 @@ namespace chaiscript
|
|||||||
std::map<std::string, Boxed_Value> m_attrs;
|
std::map<std::string, Boxed_Value> m_attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dynamic_Object_Attribute
|
namespace detail
|
||||||
{
|
{
|
||||||
static Boxed_Value func(const std::string &t_type_name, const std::string &t_attr_name,
|
struct Dynamic_Object_Attribute
|
||||||
Dynamic_Object &t_do)
|
|
||||||
{
|
{
|
||||||
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
|
||||||
/**
|
*/
|
||||||
* A Proxy_Function implementation designed for calling a function
|
class Dynamic_Object_Function : public Proxy_Function_Base
|
||||||
* that is automatically guarded based on the first param based on the
|
{
|
||||||
* param's type name
|
public:
|
||||||
*/
|
Dynamic_Object_Function(
|
||||||
class Dynamic_Object_Function : public Proxy_Function_Base
|
const std::string &t_type_name,
|
||||||
{
|
const Proxy_Function &t_func,
|
||||||
public:
|
const boost::optional<Type_Info> &t_ti = boost::optional<Type_Info>())
|
||||||
Dynamic_Object_Function(
|
: Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)),
|
||||||
const std::string &t_type_name,
|
|
||||||
const Proxy_Function &t_func,
|
|
||||||
const boost::optional<Type_Info> &t_ti = boost::optional<Type_Info>())
|
|
||||||
: 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)
|
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<const Dynamic_Object_Function *>(&f);
|
|
||||||
if (df)
|
|
||||||
{
|
{
|
||||||
return df->m_type_name == m_type_name && (*df->m_func) == (*m_func);
|
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
||||||
} else {
|
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual ~Dynamic_Object_Function() {}
|
||||||
{
|
|
||||||
if (dynamic_object_typename_match(vals, m_type_name, m_ti))
|
virtual bool operator==(const Proxy_Function_Base &f) const
|
||||||
{
|
{
|
||||||
return m_func->call_match(vals);
|
const Dynamic_Object_Function *df = dynamic_cast<const Dynamic_Object_Function *>(&f);
|
||||||
} else {
|
if (df)
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::vector<Const_Proxy_Function> get_contained_functions() const
|
|
||||||
{
|
|
||||||
std::vector<Const_Proxy_Function> 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<Boxed_Value> ¶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<Type_Info> build_param_types(
|
|
||||||
const std::vector<Type_Info> &t_inner_types, boost::optional<Type_Info> t_objectti)
|
|
||||||
{
|
|
||||||
if (t_objectti)
|
|
||||||
{
|
|
||||||
std::vector<Type_Info> types(t_inner_types);
|
|
||||||
|
|
||||||
assert(types.size() > 1);
|
|
||||||
assert(types[1].bare_equal(user_type<Boxed_Value>()));
|
|
||||||
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<Type_Info> &ti)
|
|
||||||
{
|
|
||||||
static Type_Info doti = user_type<Dynamic_Object>();
|
|
||||||
if (bv.get_type_info().bare_equal(doti))
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(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);
|
return df->m_type_name == m_type_name && (*df->m_func) == (*m_func);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
|
|
||||||
static bool dynamic_object_typename_match(const std::vector<Boxed_Value> &bvs, const std::string &name,
|
|
||||||
const boost::optional<Type_Info> &ti)
|
|
||||||
{
|
|
||||||
if (bvs.size() > 0)
|
|
||||||
{
|
{
|
||||||
return dynamic_object_typename_match(bvs[0], name, ti);
|
if (dynamic_object_typename_match(vals, m_type_name, m_ti))
|
||||||
} else {
|
{
|
||||||
return false;
|
return m_func->call_match(vals);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::vector<Const_Proxy_Function> get_contained_functions() const
|
||||||
|
{
|
||||||
|
std::vector<Const_Proxy_Function> fs;
|
||||||
|
fs.push_back(m_func);
|
||||||
|
return fs;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::string m_type_name;
|
|
||||||
Proxy_Function m_func;
|
|
||||||
boost::optional<Type_Info> m_ti;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
virtual int get_arity() const
|
||||||
* A Proxy_Function implementation designed for creating a new
|
{
|
||||||
* Dynamic_Object
|
return m_func->get_arity();
|
||||||
* that is automatically guarded based on the first param based on the
|
}
|
||||||
* param's type name
|
|
||||||
*/
|
virtual std::string annotation() const
|
||||||
class Dynamic_Object_Constructor : public Proxy_Function_Base
|
{
|
||||||
{
|
return m_func->annotation();
|
||||||
public:
|
}
|
||||||
Dynamic_Object_Constructor(
|
|
||||||
const std::string &t_type_name,
|
|
||||||
const Proxy_Function &t_func)
|
protected:
|
||||||
: Proxy_Function_Base(build_type_list(t_func->get_param_types())),
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶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<Type_Info> build_param_types(
|
||||||
|
const std::vector<Type_Info> &t_inner_types, boost::optional<Type_Info> t_objectti)
|
||||||
|
{
|
||||||
|
if (t_objectti)
|
||||||
|
{
|
||||||
|
std::vector<Type_Info> types(t_inner_types);
|
||||||
|
|
||||||
|
assert(types.size() > 1);
|
||||||
|
assert(types[1].bare_equal(user_type<Boxed_Value>()));
|
||||||
|
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<Type_Info> &ti)
|
||||||
|
{
|
||||||
|
static Type_Info doti = user_type<Dynamic_Object>();
|
||||||
|
if (bv.get_type_info().bare_equal(doti))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(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<Boxed_Value> &bvs, const std::string &name,
|
||||||
|
const boost::optional<Type_Info> &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<Type_Info> 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)
|
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<Type_Info> build_type_list(const std::vector<Type_Info> &tl)
|
|
||||||
{
|
|
||||||
std::vector<Type_Info>::const_iterator begin = tl.begin();
|
|
||||||
std::vector<Type_Info>::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<Type_Info>(begin, end);
|
static std::vector<Type_Info> build_type_list(const std::vector<Type_Info> &tl)
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Dynamic_Object_Constructor() {}
|
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &f) const
|
|
||||||
{
|
|
||||||
const Dynamic_Object_Constructor *dc = dynamic_cast<const Dynamic_Object_Constructor*>(&f);
|
|
||||||
if (dc)
|
|
||||||
{
|
{
|
||||||
return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func);
|
std::vector<Type_Info>::const_iterator begin = tl.begin();
|
||||||
} else {
|
std::vector<Type_Info>::const_iterator end = tl.end();
|
||||||
return false;
|
|
||||||
|
if (begin != end)
|
||||||
|
{
|
||||||
|
++begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::vector<Type_Info>(begin, end);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual ~Dynamic_Object_Constructor() {}
|
||||||
{
|
|
||||||
std::vector<Boxed_Value> 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 bool operator==(const Proxy_Function_Base &f) const
|
||||||
}
|
{
|
||||||
|
const Dynamic_Object_Constructor *dc = dynamic_cast<const Dynamic_Object_Constructor*>(&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<Boxed_Value> &vals) const
|
||||||
|
{
|
||||||
|
std::vector<Boxed_Value> 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
|
virtual int get_arity() const
|
||||||
{
|
{
|
||||||
// "this" is not considered part of the arity
|
// "this" is not considered part of the arity
|
||||||
return m_func->get_arity() - 1;
|
return m_func->get_arity() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const
|
||||||
{
|
{
|
||||||
return m_func->annotation();
|
return m_func->annotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||||
{
|
{
|
||||||
std::vector<Boxed_Value> new_params;
|
std::vector<Boxed_Value> new_params;
|
||||||
chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name));
|
chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name));
|
||||||
new_params.push_back(bv);
|
new_params.push_back(bv);
|
||||||
new_params.insert(new_params.end(), params.begin(), params.end());
|
new_params.insert(new_params.end(), params.begin(), params.end());
|
||||||
|
|
||||||
(*m_func)(new_params);
|
(*m_func)(new_params);
|
||||||
|
|
||||||
return bv;
|
return bv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_type_name;
|
std::string m_type_name;
|
||||||
Proxy_Function m_func;
|
Proxy_Function m_func;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -17,111 +17,115 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
/**
|
namespace detail
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
{
|
||||||
*/
|
/**
|
||||||
template<typename Ret>
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
struct Handle_Return
|
*/
|
||||||
{
|
template<typename Ret>
|
||||||
static Boxed_Value handle(const Ret &r)
|
struct Handle_Return
|
||||||
{
|
{
|
||||||
return Boxed_Value(r);
|
static Boxed_Value handle(const Ret &r)
|
||||||
}
|
{
|
||||||
};
|
return Boxed_Value(r);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<boost::shared_ptr<Ret> &>
|
struct Handle_Return<boost::shared_ptr<Ret> &>
|
||||||
{
|
|
||||||
static Boxed_Value handle(const boost::shared_ptr<Ret> &r)
|
|
||||||
{
|
{
|
||||||
return Boxed_Value(r);
|
static Boxed_Value handle(const boost::shared_ptr<Ret> &r)
|
||||||
}
|
{
|
||||||
};
|
return Boxed_Value(r);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<const boost::shared_ptr<Ret> &>
|
struct Handle_Return<const boost::shared_ptr<Ret> &>
|
||||||
{
|
|
||||||
static Boxed_Value handle(const boost::shared_ptr<Ret> &r)
|
|
||||||
{
|
{
|
||||||
return Boxed_Value(r);
|
static Boxed_Value handle(const boost::shared_ptr<Ret> &r)
|
||||||
}
|
{
|
||||||
};
|
return Boxed_Value(r);
|
||||||
|
}
|
||||||
template<typename Ret>
|
};
|
||||||
struct Handle_Return<const Ret &>
|
|
||||||
{
|
template<typename Ret>
|
||||||
static Boxed_Value handle(const Ret &r)
|
struct Handle_Return<const Ret &>
|
||||||
{
|
{
|
||||||
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
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
*/
|
*/
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<Ret &>
|
struct Handle_Return<Ret &>
|
||||||
{
|
|
||||||
static Boxed_Value handle(Ret &r)
|
|
||||||
{
|
{
|
||||||
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)
|
static Boxed_Value handle(const Ret &r)
|
||||||
{
|
{
|
||||||
return Boxed_Value(boost::cref(r));
|
return Boxed_Value(boost::cref(r));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<Boxed_Value>
|
struct Handle_Return<Boxed_Value>
|
||||||
{
|
|
||||||
static Boxed_Value handle(const Boxed_Value &r)
|
|
||||||
{
|
{
|
||||||
return r;
|
static Boxed_Value handle(const Boxed_Value &r)
|
||||||
}
|
{
|
||||||
};
|
return r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<Boxed_Value &>
|
struct Handle_Return<Boxed_Value &>
|
||||||
{
|
|
||||||
static Boxed_Value handle(const Boxed_Value &r)
|
|
||||||
{
|
{
|
||||||
return r;
|
static Boxed_Value handle(const Boxed_Value &r)
|
||||||
}
|
{
|
||||||
};
|
return r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<const Boxed_Value &>
|
struct Handle_Return<const Boxed_Value &>
|
||||||
{
|
|
||||||
static Boxed_Value handle(const Boxed_Value &r)
|
|
||||||
{
|
{
|
||||||
return r;
|
static Boxed_Value handle(const Boxed_Value &r)
|
||||||
}
|
{
|
||||||
};
|
return r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<void>
|
struct Handle_Return<void>
|
||||||
{
|
|
||||||
static Boxed_Value handle()
|
|
||||||
{
|
{
|
||||||
return Boxed_Value(Boxed_Value::Void_Type());
|
static Boxed_Value handle()
|
||||||
}
|
{
|
||||||
};
|
return Boxed_Value(Boxed_Value::Void_Type());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,446 +3,449 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace operators
|
namespace bootstrap
|
||||||
{
|
{
|
||||||
template<typename Ret, typename L, typename R>
|
namespace operators
|
||||||
Ret assign(L l, R r)
|
{
|
||||||
{
|
template<typename Ret, typename L, typename R>
|
||||||
return (l = r);
|
Ret assign(L l, R r)
|
||||||
}
|
{
|
||||||
|
return (l = r);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_bitwise_and(L l, R r)
|
Ret assign_bitwise_and(L l, R r)
|
||||||
{
|
{
|
||||||
return (l &= r);
|
return (l &= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_xor(L l, R r)
|
Ret assign_xor(L l, R r)
|
||||||
{
|
{
|
||||||
return (l ^= r);
|
return (l ^= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_bitwise_or(L l, R r)
|
Ret assign_bitwise_or(L l, R r)
|
||||||
{
|
{
|
||||||
return (l |= r);
|
return (l |= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_difference(L l, R r)
|
Ret assign_difference(L l, R r)
|
||||||
{
|
{
|
||||||
return (l -= r);
|
return (l -= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_left_shift(L l, R r)
|
Ret assign_left_shift(L l, R r)
|
||||||
{
|
{
|
||||||
return (l <<= r);
|
return (l <<= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_product(L l, R r)
|
Ret assign_product(L l, R r)
|
||||||
{
|
{
|
||||||
return (l *= r);
|
return (l *= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_quotient(L l, R r)
|
Ret assign_quotient(L l, R r)
|
||||||
{
|
{
|
||||||
return (l /= r);
|
return (l /= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_remainder(L l, R r)
|
Ret assign_remainder(L l, R r)
|
||||||
{
|
{
|
||||||
return (l %= r);
|
return (l %= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_right_shift(L l, R r)
|
Ret assign_right_shift(L l, R r)
|
||||||
{
|
{
|
||||||
return (l >>= r);
|
return (l >>= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret assign_sum(L l, R r)
|
Ret assign_sum(L l, R r)
|
||||||
{
|
{
|
||||||
return (l += r);
|
return (l += r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L>
|
template<typename Ret, typename L>
|
||||||
Ret prefix_decrement(L l)
|
Ret prefix_decrement(L l)
|
||||||
{
|
{
|
||||||
return (--l);
|
return (--l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L>
|
template<typename Ret, typename L>
|
||||||
Ret prefix_increment(L l)
|
Ret prefix_increment(L l)
|
||||||
{
|
{
|
||||||
return (++l);
|
return (++l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret equal(L l, R r)
|
Ret equal(L l, R r)
|
||||||
{
|
{
|
||||||
return (l == r);
|
return (l == r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret greater_than(L l, R r)
|
Ret greater_than(L l, R r)
|
||||||
{
|
{
|
||||||
return (l > r);
|
return (l > r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret greater_than_equal(L l, R r)
|
Ret greater_than_equal(L l, R r)
|
||||||
{
|
{
|
||||||
return (l >= r);
|
return (l >= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret less_than(L l, R r)
|
Ret less_than(L l, R r)
|
||||||
{
|
{
|
||||||
return (l < r);
|
return (l < r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret less_than_equal(L l, R r)
|
Ret less_than_equal(L l, R r)
|
||||||
{
|
{
|
||||||
return (l <= r);
|
return (l <= r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L>
|
template<typename Ret, typename L>
|
||||||
Ret logical_compliment(L l)
|
Ret logical_compliment(L l)
|
||||||
{
|
{
|
||||||
return (!l);
|
return (!l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret not_equal(L l, R r)
|
Ret not_equal(L l, R r)
|
||||||
{
|
{
|
||||||
return (l != r);
|
return (l != r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret addition(L l, R r)
|
Ret addition(L l, R r)
|
||||||
{
|
{
|
||||||
return (l + r);
|
return (l + r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L>
|
template<typename Ret, typename L>
|
||||||
Ret unary_plus(L l)
|
Ret unary_plus(L l)
|
||||||
{
|
{
|
||||||
return (+l);
|
return (+l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret subtraction(L l, R r)
|
Ret subtraction(L l, R r)
|
||||||
{
|
{
|
||||||
return (l - r);
|
return (l - r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L>
|
template<typename Ret, typename L>
|
||||||
Ret unary_minus(L l)
|
Ret unary_minus(L l)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_MSVC
|
#ifdef BOOST_MSVC
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4146)
|
#pragma warning(disable : 4146)
|
||||||
return (-l);
|
return (-l);
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#else
|
#else
|
||||||
return (-l);
|
return (-l);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret bitwise_and(L l, R r)
|
Ret bitwise_and(L l, R r)
|
||||||
{
|
{
|
||||||
return (l & r);
|
return (l & r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L>
|
template<typename Ret, typename L>
|
||||||
Ret bitwise_compliment(L l)
|
Ret bitwise_compliment(L l)
|
||||||
{
|
{
|
||||||
return (~l);
|
return (~l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret bitwise_xor(L l, R r)
|
Ret bitwise_xor(L l, R r)
|
||||||
{
|
{
|
||||||
return (l ^ r);
|
return (l ^ r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret bitwise_or(L l, R r)
|
Ret bitwise_or(L l, R r)
|
||||||
{
|
{
|
||||||
return (l | r);
|
return (l | r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret division(L l, R r)
|
Ret division(L l, R r)
|
||||||
{
|
{
|
||||||
return (l / r);
|
return (l / r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret left_shift(L l, R r)
|
Ret left_shift(L l, R r)
|
||||||
{
|
{
|
||||||
return l << r;
|
return l << r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret multiplication(L l, R r)
|
Ret multiplication(L l, R r)
|
||||||
{
|
{
|
||||||
return l * r;
|
return l * r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret remainder(L l, R r)
|
Ret remainder(L l, R r)
|
||||||
{
|
{
|
||||||
return (l % r);
|
return (l % r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename L, typename R>
|
template<typename Ret, typename L, typename R>
|
||||||
Ret right_shift(L l, R r)
|
Ret right_shift(L l, R r)
|
||||||
{
|
{
|
||||||
return (l >> r);
|
return (l >> r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign<T &, T &, const T&>), "=");
|
m->add(fun(&assign<T &, T &, const T&>), "=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_bitwise_and(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_bitwise_and(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_bitwise_and<T &, T &, const T&>), "&=");
|
m->add(fun(&assign_bitwise_and<T &, T &, const T&>), "&=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_xor(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_xor(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_xor<T &, T &, const T&>), "^=");
|
m->add(fun(&assign_xor<T &, T &, const T&>), "^=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_bitwise_or(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_bitwise_or(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_bitwise_or<T &, T &, const T&>), "|=");
|
m->add(fun(&assign_bitwise_or<T &, T &, const T&>), "|=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_difference(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_difference(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_difference<T &, T &, const T&>), "-=");
|
m->add(fun(&assign_difference<T &, T &, const T&>), "-=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_left_shift(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_left_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_left_shift<T &, T &, const T&>), "<<=");
|
m->add(fun(&assign_left_shift<T &, T &, const T&>), "<<=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_product(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_product(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_product<T &, T &, const T&>), "*=");
|
m->add(fun(&assign_product<T &, T &, const T&>), "*=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_quotient(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_quotient(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_quotient<T &, T &, const T&>), "/=");
|
m->add(fun(&assign_quotient<T &, T &, const T&>), "/=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_remainder(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_remainder(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_remainder<T &, T &, const T&>), "%=");
|
m->add(fun(&assign_remainder<T &, T &, const T&>), "%=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_right_shift(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_right_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_right_shift<T &, T &, const T&>), ">>=");
|
m->add(fun(&assign_right_shift<T &, T &, const T&>), ">>=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_sum(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assign_sum(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&assign_sum<T &, T &, const T&>), "+=");
|
m->add(fun(&assign_sum<T &, T &, const T&>), "+=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr prefix_decrement(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr prefix_decrement(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&prefix_decrement<T &, T &>), "--");
|
m->add(fun(&prefix_decrement<T &, T &>), "--");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr prefix_increment(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr prefix_increment(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&prefix_increment<T &, T &>), "++");
|
m->add(fun(&prefix_increment<T &, T &>), "++");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr equal(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&equal<bool, const T&, const T&>), "==");
|
m->add(fun(&equal<bool, const T&, const T&>), "==");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr greater_than(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr greater_than(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&greater_than<bool, const T&, const T&>), ">");
|
m->add(fun(&greater_than<bool, const T&, const T&>), ">");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr greater_than_equal(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr greater_than_equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&greater_than_equal<bool, const T&, const T&>), ">=");
|
m->add(fun(&greater_than_equal<bool, const T&, const T&>), ">=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr less_than(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr less_than(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&less_than<bool, const T&, const T&>), "<");
|
m->add(fun(&less_than<bool, const T&, const T&>), "<");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr less_than_equal(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr less_than_equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&less_than_equal<bool, const T&, const T&>), "<=");
|
m->add(fun(&less_than_equal<bool, const T&, const T&>), "<=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr logical_compliment(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr logical_compliment(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&logical_compliment<bool, const T &>), "!");
|
m->add(fun(&logical_compliment<bool, const T &>), "!");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr not_equal(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr not_equal(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(¬_equal<bool, const T &, const T &>), "!=");
|
m->add(fun(¬_equal<bool, const T &, const T &>), "!=");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr addition(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr addition(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&addition<T, const T &, const T &>), "+");
|
m->add(fun(&addition<T, const T &, const T &>), "+");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr unary_plus(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr unary_plus(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&unary_plus<T, const T &>), "+");
|
m->add(fun(&unary_plus<T, const T &>), "+");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr subtraction(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr subtraction(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&subtraction<T, const T &, const T &>), "-");
|
m->add(fun(&subtraction<T, const T &, const T &>), "-");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr unary_minus(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr unary_minus(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&unary_minus<T, const T &>), "-");
|
m->add(fun(&unary_minus<T, const T &>), "-");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_and(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr bitwise_and(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&bitwise_and<T, const T &, const T &>), "&");
|
m->add(fun(&bitwise_and<T, const T &, const T &>), "&");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_compliment(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr bitwise_compliment(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&bitwise_compliment<T, const T &>), "~");
|
m->add(fun(&bitwise_compliment<T, const T &>), "~");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_xor(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr bitwise_xor(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&bitwise_xor<T, const T &, const T &>), "^");
|
m->add(fun(&bitwise_xor<T, const T &, const T &>), "^");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_or(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr bitwise_or(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&bitwise_or<T, const T &, const T &>), "|");
|
m->add(fun(&bitwise_or<T, const T &, const T &>), "|");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr division(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr division(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&division<T, const T &, const T &>), "/");
|
m->add(fun(&division<T, const T &, const T &>), "/");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr left_shift(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr left_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&left_shift<T, const T &, const T &>), "<<");
|
m->add(fun(&left_shift<T, const T &, const T &>), "<<");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr multiplication(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr multiplication(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&multiplication<T, const T &, const T &>), "*");
|
m->add(fun(&multiplication<T, const T &, const T &>), "*");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr remainder(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr remainder(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&remainder<T, const T &, const T &>), "%");
|
m->add(fun(&remainder<T, const T &, const T &>), "%");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr right_shift(ModulePtr m = ModulePtr(new Module()))
|
ModulePtr right_shift(ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun(&right_shift<T, const T &, const T &>), ">>");
|
m->add(fun(&right_shift<T, const T &, const T &>), ">>");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,19 +175,22 @@ namespace chaiscript
|
|||||||
typedef boost::shared_ptr<Proxy_Function_Base> Proxy_Function;
|
typedef boost::shared_ptr<Proxy_Function_Base> Proxy_Function;
|
||||||
typedef boost::shared_ptr<const Proxy_Function_Base> Const_Proxy_Function;
|
typedef boost::shared_ptr<const Proxy_Function_Base> Const_Proxy_Function;
|
||||||
|
|
||||||
/**
|
namespace exception
|
||||||
* Exception thrown if a function's guard fails to execute
|
|
||||||
*/
|
|
||||||
class guard_error : public std::runtime_error
|
|
||||||
{
|
{
|
||||||
public:
|
/**
|
||||||
guard_error() throw()
|
* Exception thrown if a function's guard fails to execute
|
||||||
: std::runtime_error("Guard evaluation failed")
|
*/
|
||||||
{ }
|
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
|
* A Proxy_Function implementation that is not type safe, the called function
|
||||||
@ -251,11 +254,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
return m_f(params);
|
return m_f(params);
|
||||||
} else {
|
} else {
|
||||||
throw guard_error();
|
throw exception::guard_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw arity_error(static_cast<int>(params.size()), m_arity);
|
throw exception::arity_error(static_cast<int>(params.size()), m_arity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,9 +269,9 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return boxed_cast<bool>((*m_guard)(params));
|
return boxed_cast<bool>((*m_guard)(params));
|
||||||
} catch (const arity_error &) {
|
} catch (const exception::arity_error &) {
|
||||||
return false;
|
return false;
|
||||||
} catch (const bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -438,7 +441,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Proxy_Function_Impl(const boost::function<Func> &f)
|
Proxy_Function_Impl(const boost::function<Func> &f)
|
||||||
: Proxy_Function_Base(build_param_type_list(static_cast<Func *>(0))),
|
: Proxy_Function_Base(detail::build_param_type_list(static_cast<Func *>(0))),
|
||||||
m_f(f), m_dummy_func(0)
|
m_f(f), m_dummy_func(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -465,7 +468,7 @@ namespace chaiscript
|
|||||||
return false;
|
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
|
virtual std::string annotation() const
|
||||||
@ -481,7 +484,7 @@ namespace chaiscript
|
|||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||||
{
|
{
|
||||||
return Do_Call<typename boost::function<Func>::result_type>::go(m_f, params);
|
return detail::Do_Call<typename boost::function<Func>::result_type>::go(m_f, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -545,13 +548,13 @@ namespace chaiscript
|
|||||||
if (bv.is_const())
|
if (bv.is_const())
|
||||||
{
|
{
|
||||||
const Class *o = boxed_cast<const Class *>(bv);
|
const Class *o = boxed_cast<const Class *>(bv);
|
||||||
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
return detail::Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||||
} else {
|
} else {
|
||||||
Class *o = boxed_cast<Class *>(bv);
|
Class *o = boxed_cast<Class *>(bv);
|
||||||
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
return detail::Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw arity_error(static_cast<int>(params.size()), 1);
|
throw exception::arity_error(static_cast<int>(params.size()), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,11 +606,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
return (*(*begin))(plist);
|
return (*(*begin))(plist);
|
||||||
}
|
}
|
||||||
} catch (const bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
//parameter failed to cast, try again
|
//parameter failed to cast, try again
|
||||||
} catch (const arity_error &) {
|
} catch (const exception::arity_error &) {
|
||||||
//invalid num params, try again
|
//invalid num params, try again
|
||||||
} catch (const guard_error &) {
|
} catch (const exception::guard_error &) {
|
||||||
//guard failed to allow the function to execute,
|
//guard failed to allow the function to execute,
|
||||||
//try again
|
//try again
|
||||||
}
|
}
|
||||||
|
@ -28,43 +28,50 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
/**
|
namespace exception
|
||||||
* Exception thrown when there is a mismatch in number of
|
|
||||||
* parameters during Proxy_Function execution
|
|
||||||
*/
|
|
||||||
struct arity_error : std::range_error
|
|
||||||
{
|
{
|
||||||
arity_error(int t_got, int t_expected)
|
/**
|
||||||
: std::range_error("Function dispatch arity mismatch"),
|
* Exception thrown when there is a mismatch in number of
|
||||||
got(t_got), expected(t_expected)
|
* parameters during Proxy_Function execution
|
||||||
|
*/
|
||||||
|
struct arity_error : std::range_error
|
||||||
{
|
{
|
||||||
}
|
arity_error(int t_got, int t_expected)
|
||||||
|
: std::range_error("Function dispatch arity mismatch"),
|
||||||
virtual ~arity_error() throw() {}
|
got(t_got), expected(t_expected)
|
||||||
int got;
|
|
||||||
int expected;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Ret>
|
|
||||||
struct Do_Call
|
|
||||||
{
|
|
||||||
template<typename Fun>
|
|
||||||
static Boxed_Value go(const boost::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
{
|
||||||
return Handle_Return<Ret>::handle(call_func(fun, params));
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
virtual ~arity_error() throw() {}
|
||||||
struct Do_Call<void>
|
|
||||||
{
|
int got;
|
||||||
template<typename Fun>
|
int expected;
|
||||||
static Boxed_Value go(const boost::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
|
||||||
call_func(fun, params);
|
|
||||||
return Handle_Return<void>::handle();
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename Ret>
|
||||||
|
struct Do_Call
|
||||||
|
{
|
||||||
|
template<typename Fun>
|
||||||
|
static Boxed_Value go(const boost::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
return Handle_Return<Ret>::handle(call_func(fun, params));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Do_Call<void>
|
||||||
|
{
|
||||||
|
template<typename Fun>
|
||||||
|
static Boxed_Value go(const boost::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
call_func(fun, params);
|
||||||
|
return Handle_Return<void>::handle();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
||||||
@ -78,57 +85,59 @@ namespace chaiscript
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
/**
|
namespace detail
|
||||||
* Used by Proxy_Function_Impl to return a list of all param types
|
{
|
||||||
* it contains.
|
/**
|
||||||
*/
|
* Used by Proxy_Function_Impl to return a list of all param types
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
* it contains.
|
||||||
std::vector<Type_Info> build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
*/
|
||||||
{
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
std::vector<Type_Info> ti;
|
std::vector<Type_Info> build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
|
||||||
ti.push_back(detail::Get_Type_Info<Ret>::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<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
|
||||||
Ret call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
|
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() != n)
|
|
||||||
{
|
{
|
||||||
throw arity_error(static_cast<int>(params.size()), n);
|
std::vector<Type_Info> ti;
|
||||||
} else {
|
ti.push_back(detail::Get_Type_Info<Ret>::get());
|
||||||
return f(BOOST_PP_REPEAT(n, casthelper, ~));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
BOOST_PP_REPEAT(n, gettypeinfo, ~)
|
||||||
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
|
||||||
* Proxy_Function_Impl object. This function is primarly used to prevent
|
return ti;
|
||||||
* registration of two functions with the exact same signatures
|
|
||||||
*/
|
|
||||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
|
||||||
bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)),
|
|
||||||
const std::vector<Boxed_Value> & BOOST_PP_IF(n, params, ))
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
BOOST_PP_REPEAT(n, trycast, ~);
|
|
||||||
} catch (const bad_boxed_cast &) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||||
|
Ret call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
|
||||||
|
const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
if (params.size() != n)
|
||||||
|
{
|
||||||
|
throw exception::arity_error(static_cast<int>(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<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
|
||||||
|
bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)),
|
||||||
|
const std::vector<Boxed_Value> & BOOST_PP_IF(n, params, ))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
BOOST_PP_REPEAT(n, trycast, ~);
|
||||||
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef n
|
#undef n
|
||||||
|
@ -78,13 +78,13 @@ namespace chaiscript
|
|||||||
template<typename T, typename Q>
|
template<typename T, typename Q>
|
||||||
Proxy_Function fun(T t, const Q &q)
|
Proxy_Function fun(T t, const Q &q)
|
||||||
{
|
{
|
||||||
return fun(bind_first(t, q));
|
return fun(detail::bind_first(t, q));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Q, typename R>
|
template<typename T, typename Q, typename R>
|
||||||
Proxy_Function fun(T t, const Q &q, const R &r)
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -204,14 +204,14 @@ namespace chaiscript
|
|||||||
&typeid(typename Bare_Type<T>::type));
|
&typeid(typename Bare_Type<T>::type));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Stripped_Type
|
||||||
|
{
|
||||||
|
typedef typename Bare_Type<typename detail::Get_Type_Info<T>::type>::type type;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct Stripped_Type
|
|
||||||
{
|
|
||||||
typedef typename Bare_Type<typename detail::Get_Type_Info<T>::type>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Type_Info user_type(T)
|
Type_Info user_type(T)
|
||||||
{
|
{
|
||||||
|
@ -552,10 +552,10 @@ namespace chaiscript
|
|||||||
m_engine.add(fun(static_cast<load_mod_1>(&ChaiScript::load_module), this), "load_module");
|
m_engine.add(fun(static_cast<load_mod_1>(&ChaiScript::load_module), this), "load_module");
|
||||||
m_engine.add(fun(static_cast<load_mod_2>(&ChaiScript::load_module), this), "load_module");
|
m_engine.add(fun(static_cast<load_mod_2>(&ChaiScript::load_module), this), "load_module");
|
||||||
|
|
||||||
add(vector_type<std::vector<Boxed_Value> >("Vector"));
|
add(standard_library::vector_type<std::vector<Boxed_Value> >("Vector"));
|
||||||
add(string_type<std::string>("string"));
|
add(standard_library::string_type<std::string>("string"));
|
||||||
add(map_type<std::map<std::string, Boxed_Value> >("Map"));
|
add(standard_library::map_type<std::map<std::string, Boxed_Value> >("Map"));
|
||||||
add(pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
|
add(standard_library::pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
|
||||||
|
|
||||||
m_engine.add(fun(&ChaiScript::use, this), "use");
|
m_engine.add(fun(&ChaiScript::use, this), "use");
|
||||||
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
|
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
|
||||||
|
@ -662,7 +662,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
t_ss.pop_scope();
|
t_ss.pop_scope();
|
||||||
throw Eval_Error("While condition not boolean");
|
throw Eval_Error("While condition not boolean");
|
||||||
}
|
}
|
||||||
@ -684,7 +684,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
t_ss.pop_scope();
|
t_ss.pop_scope();
|
||||||
throw Eval_Error("While condition not boolean");
|
throw Eval_Error("While condition not boolean");
|
||||||
}
|
}
|
||||||
@ -714,7 +714,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw Eval_Error("If condition not boolean");
|
throw Eval_Error("If condition not boolean");
|
||||||
}
|
}
|
||||||
catch (Eval_Error &ee) {
|
catch (Eval_Error &ee) {
|
||||||
@ -748,7 +748,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[i+1]->eval(t_ss));
|
cond = boxed_cast<bool>(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");
|
throw Eval_Error("'else if' condition not boolean");
|
||||||
}
|
}
|
||||||
catch (Eval_Error &ee) {
|
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();
|
t_ss.pop_scope();
|
||||||
throw Eval_Error("For condition not boolean");
|
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();
|
t_ss.pop_scope();
|
||||||
throw Eval_Error("For condition not boolean");
|
throw Eval_Error("For condition not boolean");
|
||||||
}
|
}
|
||||||
@ -1120,7 +1120,7 @@ namespace chaiscript
|
|||||||
bool guard;
|
bool guard;
|
||||||
try {
|
try {
|
||||||
guard = boxed_cast<bool>(catch_block->children[1]->eval(t_ss));
|
guard = boxed_cast<bool>(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) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
try {
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
@ -1200,7 +1200,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
guard = boxed_cast<bool>(catch_block->children[1]->eval(t_ss));
|
guard = boxed_cast<bool>(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) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
try {
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
@ -1339,7 +1339,7 @@ namespace chaiscript
|
|||||||
const std::string & function_name = this->children[1]->text;
|
const std::string & function_name = this->children[1]->text;
|
||||||
if (function_name == class_name) {
|
if (function_name == class_name) {
|
||||||
t_ss.add(Proxy_Function
|
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<Dispatch_Engine>,
|
(new Dynamic_Proxy_Function(boost::bind(&eval_function<Dispatch_Engine>,
|
||||||
boost::ref(t_ss), this->children.back(),
|
boost::ref(t_ss), this->children.back(),
|
||||||
t_param_names, _1), static_cast<int>(numparams), this->children.back(),
|
t_param_names, _1), static_cast<int>(numparams), this->children.back(),
|
||||||
@ -1354,7 +1354,7 @@ namespace chaiscript
|
|||||||
// No biggie, the type name is just not known
|
// No biggie, the type name is just not known
|
||||||
}
|
}
|
||||||
t_ss.add(Proxy_Function
|
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<Dispatch_Engine>,
|
(new Dynamic_Proxy_Function(boost::bind(&eval_function<Dispatch_Engine>,
|
||||||
boost::ref(t_ss), this->children.back(),
|
boost::ref(t_ss), this->children.back(),
|
||||||
t_param_names, _1), static_cast<int>(numparams), this->children.back(),
|
t_param_names, _1), static_cast<int>(numparams), this->children.back(),
|
||||||
@ -1377,7 +1377,7 @@ namespace chaiscript
|
|||||||
virtual ~Attr_Decl_AST_Node() {}
|
virtual ~Attr_Decl_AST_Node() {}
|
||||||
virtual Boxed_Value eval(Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval(Dispatch_Engine &t_ss){
|
||||||
try {
|
try {
|
||||||
t_ss.add(fun(boost::function<Boxed_Value (Dynamic_Object &)>(boost::bind(&Dynamic_Object_Attribute::func, this->children[0]->text,
|
t_ss.add(fun(boost::function<Boxed_Value (Dynamic_Object &)>(boost::bind(&detail::Dynamic_Object_Attribute::func, this->children[0]->text,
|
||||||
this->children[1]->text, _1))), this->children[1]->text);
|
this->children[1]->text, _1))), this->children[1]->text);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1445,7 +1445,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
lhs = boxed_cast<bool>(retval);
|
lhs = boxed_cast<bool>(retval);
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw Eval_Error("Condition not boolean");
|
throw Eval_Error("Condition not boolean");
|
||||||
}
|
}
|
||||||
if (lhs) {
|
if (lhs) {
|
||||||
@ -1488,7 +1488,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
lhs = boxed_cast<bool>(retval);
|
lhs = boxed_cast<bool>(retval);
|
||||||
}
|
}
|
||||||
catch (const bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw Eval_Error("Condition not boolean");
|
throw Eval_Error("Condition not boolean");
|
||||||
}
|
}
|
||||||
if (lhs) {
|
if (lhs) {
|
||||||
|
@ -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
|
//Ability to create our own container types when needed. std::vector and std::map are
|
||||||
//mostly supported currently
|
//mostly supported currently
|
||||||
chai.add(bootstrap::vector_type<std::vector<int> >("IntVector"));
|
chai.add(bootstrap::standard_library::vector_type<std::vector<int> >("IntVector"));
|
||||||
|
|
||||||
|
|
||||||
// Test ability to register a function that excepts a shared_ptr version of a type
|
// 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");
|
chai.add(fun(&bound_log, std::string("Msg")), "BoundFun");
|
||||||
|
|
||||||
//Dynamic objects test
|
//Dynamic objects test
|
||||||
chai.add(chaiscript::Proxy_Function(new Dynamic_Object_Function("TestType", fun(&hello_world))), "hello_world");
|
chai.add(chaiscript::Proxy_Function(new detail::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(chaiscript::Proxy_Function(new detail::Dynamic_Object_Constructor("TestType", fun(&hello_constructor))), "TestType");
|
||||||
chai.add(fun(boost::function<Boxed_Value (Dynamic_Object &)>(boost::bind(&Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr");
|
chai.add(fun(boost::function<Boxed_Value (Dynamic_Object &)>(boost::bind(&detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr");
|
||||||
|
|
||||||
chai.eval("var x = TestType()");
|
chai.eval("var x = TestType()");
|
||||||
// chai.eval("x.attr = \"hi\"");
|
// chai.eval("x.attr = \"hi\"");
|
||||||
|
@ -48,7 +48,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
|
|||||||
m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
|
m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
|
||||||
|
|
||||||
|
|
||||||
chaiscript::bootstrap::vector_type<std::vector<boost::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
|
chaiscript::bootstrap::standard_library::vector_type<std::vector<boost::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
|
||||||
|
|
||||||
CHAISCRIPT_CLASS( m,
|
CHAISCRIPT_CLASS( m,
|
||||||
chaiscript::File_Position,
|
chaiscript::File_Position,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extra()
|
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extra()
|
||||||
{
|
{
|
||||||
return chaiscript::bootstrap::list_type<std::list<chaiscript::Boxed_Value> >("List");
|
return chaiscript::bootstrap::standard_library::list_type<std::list<chaiscript::Boxed_Value> >("List");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass)
|
|||||||
try {
|
try {
|
||||||
To ret = chaiscript::boxed_cast<To>(bv);
|
To ret = chaiscript::boxed_cast<To>(bv);
|
||||||
use(ret);
|
use(ret);
|
||||||
} catch (const chaiscript::bad_boxed_cast &/*e*/) {
|
} catch (const chaiscript::exception::bad_boxed_cast &/*e*/) {
|
||||||
if (expectedpass) {
|
if (expectedpass) {
|
||||||
// std::cerr << "Failure in run_test_type_conversion: " << e.what() << std::endl;
|
// std::cerr << "Failure in run_test_type_conversion: " << e.what() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
@ -274,7 +274,7 @@ bool pointer_test(const T& default_value, const T& new_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (const bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
std::cerr << "Bad boxed cast performing ** to ** test" << std::endl;
|
std::cerr << "Bad boxed cast performing ** to ** test" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user