Removing stale first attempt
This commit is contained in:
		@@ -1,23 +0,0 @@
 | 
			
		||||
cmake_minimum_required(VERSION 2.6)
 | 
			
		||||
enable_testing()
 | 
			
		||||
 | 
			
		||||
project(boxedcpp)
 | 
			
		||||
 | 
			
		||||
SET (CMAKE_BUILD_TYPE gdb)
 | 
			
		||||
SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb")
 | 
			
		||||
SET (CMAKE_CXX_FLAGS_GDB " -Wall -ggdb")
 | 
			
		||||
 | 
			
		||||
find_package( Boost 1.36.0 COMPONENTS regex unit_test_framework)
 | 
			
		||||
if(Boost_FOUND)
 | 
			
		||||
   include_directories(${Boost_INCLUDE_DIRS})
 | 
			
		||||
   include_directories(.)
 | 
			
		||||
   
 | 
			
		||||
   add_executable(boxedcpp_test test.cpp)
 | 
			
		||||
 | 
			
		||||
   add_executable(boxedcpp_unittest unittest.cpp)
 | 
			
		||||
 | 
			
		||||
   target_link_libraries(boxedcpp_unittest ${Boost_LIBRARIES})
 | 
			
		||||
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_test(boxedcpp_unittest boxedcpp_unittest)
 | 
			
		||||
@@ -1,522 +0,0 @@
 | 
			
		||||
#ifndef __bootstrap_hpp
 | 
			
		||||
#define __bootstrap_hpp__
 | 
			
		||||
 | 
			
		||||
#include "boxedcpp.hpp"
 | 
			
		||||
#include "register_function.hpp"
 | 
			
		||||
 | 
			
		||||
template<typename Ret, typename P1, typename P2>
 | 
			
		||||
Ret add(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 + p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Boxed_Value pod_add(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l + r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Ret, typename P1, typename P2>
 | 
			
		||||
Ret subtract(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 - p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Boxed_Value pod_subtract(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l - r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Ret, typename P1, typename P2>
 | 
			
		||||
Ret divide(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 / p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Boxed_Value pod_divide(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l / r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Ret, typename P1, typename P2>
 | 
			
		||||
Ret multiply(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 * p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Boxed_Value pod_multiply(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l * r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool bool_and(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 && p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool bool_or(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 || p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
P1 &assign(P1 &p1, const P2 &p2)
 | 
			
		||||
{
 | 
			
		||||
  return (p1 = p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 &assign_pod(P1 &p1, Boxed_POD_Value v)
 | 
			
		||||
{
 | 
			
		||||
  if (v.m_isfloat)
 | 
			
		||||
  {
 | 
			
		||||
    return (p1 = v.d);
 | 
			
		||||
  } else {
 | 
			
		||||
    return (p1 = v.i);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool equals(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 == p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pod_equals(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l == r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool not_equals(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 != p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pod_not_equals(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l != r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool less_than(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 < p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pod_less_than(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l < r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool greater_than(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 > p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pod_greater_than(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l > r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool less_than_equals(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 <= p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pod_less_than_equals(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l <= r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
bool greater_than_equals(P1 p1, P2 p2)
 | 
			
		||||
{
 | 
			
		||||
  return p1 >= p2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pod_greater_than_equals(Boxed_POD_Value l, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  return l >= r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
P1 ×equal(P1 &p1, const P2 &p2)
 | 
			
		||||
{
 | 
			
		||||
  return (p1 *= p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 ×equal_pod(P1 &p1, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  if (r.m_isfloat)
 | 
			
		||||
  {
 | 
			
		||||
    return (p1 *= r.d);
 | 
			
		||||
  } else {
 | 
			
		||||
    return (p1 *= r.i);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
P1 ÷sequal(P1 &p1, const P2 &p2)
 | 
			
		||||
{
 | 
			
		||||
  return (p1 /= p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 ÷sequal_pod(P1 &p1, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  if (r.m_isfloat)
 | 
			
		||||
  {
 | 
			
		||||
    return (p1 /= r.d);
 | 
			
		||||
  } else {
 | 
			
		||||
    return (p1 /= r.i);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
P1 &addsequal(P1 &p1, const P2 &p2)
 | 
			
		||||
{
 | 
			
		||||
  return (p1 += p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 &addsequal_pod(P1 &p1, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  if (r.m_isfloat)
 | 
			
		||||
  {
 | 
			
		||||
    return (p1 += r.d);
 | 
			
		||||
  } else {
 | 
			
		||||
    return (p1 += r.i);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1, typename P2>
 | 
			
		||||
P1 &subtractsequal(P1 &p1, const P2 &p2)
 | 
			
		||||
{
 | 
			
		||||
  return (p1 -= p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 &subtractsequal_pod(P1 &p1, Boxed_POD_Value r)
 | 
			
		||||
{
 | 
			
		||||
  if (r.m_isfloat)
 | 
			
		||||
  {
 | 
			
		||||
    return (p1 -= r.d);
 | 
			
		||||
  } else {
 | 
			
		||||
    return (p1 -= r.i);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 &prefixincrement(P1 &p1)
 | 
			
		||||
{
 | 
			
		||||
  return (++p1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 &prefixdecrement(P1 &p1)
 | 
			
		||||
{
 | 
			
		||||
  return (--p1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 &prefixnegate(P1 &p1)
 | 
			
		||||
{
 | 
			
		||||
  return (p1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename P1>
 | 
			
		||||
P1 &prefixnot(P1 &p1)
 | 
			
		||||
{
 | 
			
		||||
  return (p1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//Add canonical forms of operators
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_equals(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &equals<const T&, const T&>, "=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_add(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &add<T, const T&, const T&>, "+");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_add_equals(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &addsequal<T, T>, "+=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_subtract(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &subtract<T, const T&, const T&>, "-");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_divide(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, ÷<T, const T&, const T&>, "-");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_multiply(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &multiply<T, const T&, const T&>, "*");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_not_equals(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, ¬_equals<const T&, const T&>, "!=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename U>
 | 
			
		||||
void add_oper_assign_overload(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &assign<T,U>, "=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_assign(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &assign<T,T>, "=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_assign_pod(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &assign_pod<T>, "=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_less_than(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &less_than<const T&, const T&>, "<");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_greater_than(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &greater_than<const T&, const T&>, ">");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_less_than_equals(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &less_than_equals<const T&, const T&>, "<=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_oper_greater_than_equals(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &greater_than_equals<const T&, const T&>, ">=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T, typename R>
 | 
			
		||||
void add_opers_comparison_overload(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &equals<const T&, const R&>, "==");
 | 
			
		||||
  register_function(s, ¬_equals<const T&, const R&>, "!=");
 | 
			
		||||
  register_function(s, &less_than<const T&, const R&>, "<");
 | 
			
		||||
  register_function(s, &greater_than<const T&, const R&>, ">");
 | 
			
		||||
  register_function(s, &less_than_equals<const T&, const R&>, "<=");
 | 
			
		||||
  register_function(s, &greater_than_equals<const T&, const R&>, ">=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void add_opers_comparison_pod(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &pod_equals, "==");
 | 
			
		||||
  register_function(s, &pod_not_equals, "!=");
 | 
			
		||||
  register_function(s, &pod_less_than, "<");
 | 
			
		||||
  register_function(s, &pod_greater_than, ">");
 | 
			
		||||
  register_function(s, &pod_less_than_equals, "<=");
 | 
			
		||||
  register_function(s, &pod_greater_than_equals, ">=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void add_opers_arithmetic_pod(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &pod_add, "+");
 | 
			
		||||
  register_function(s, &pod_subtract, "-");
 | 
			
		||||
  register_function(s, &pod_divide, "/");
 | 
			
		||||
  register_function(s, &pod_multiply, "*");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_opers_comparison(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  add_opers_comparison_overload<T, T>(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Ret, typename T, typename R>
 | 
			
		||||
void add_opers_arithmetic_overload(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, &add<Ret, T, R>, "+");
 | 
			
		||||
  register_function(s, &subtract<Ret, T, R>, "-");
 | 
			
		||||
  register_function(s, ÷<Ret, T, R>, "/");
 | 
			
		||||
  register_function(s, &multiply<Ret, T, R>, "*");
 | 
			
		||||
  register_function(s, ×equal<T, R>, "*=");
 | 
			
		||||
  register_function(s, ÷sequal<T, R>, "/=");
 | 
			
		||||
  register_function(s, &subtractsequal<T, R>, "-=");
 | 
			
		||||
  register_function(s, &addsequal<T, R>, "+=");
 | 
			
		||||
  register_function(s, &prefixincrement<T>, "++");
 | 
			
		||||
  register_function(s, &prefixdecrement<T>, "--");
 | 
			
		||||
  register_function(s, &prefixnegate<T>, "-");
 | 
			
		||||
  register_function(s, &prefixnot<T>, "!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_opers_arithmetic_modify_pod(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  register_function(s, ×equal_pod<T>, "*=");
 | 
			
		||||
  register_function(s, ÷sequal_pod<T>, "/=");
 | 
			
		||||
  register_function(s, &subtractsequal_pod<T>, "-=");
 | 
			
		||||
  register_function(s, &addsequal_pod<T>, "+=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_basic_constructors(Dispatch_Engine &s, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  s.register_function(build_constructor<T>(), type);
 | 
			
		||||
  s.register_function(build_constructor<T, const T &>(), type);
 | 
			
		||||
  s.register_function(build_constructor<T, const T &>(), "clone");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename U>
 | 
			
		||||
void add_constructor_overload(Dispatch_Engine &s, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  s.register_function(build_constructor<T, const U &>(), type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void add_opers_arithmetic(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  add_opers_arithmetic_overload<T, T, T>(s);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class bad_boxed_value_cast : public std::bad_cast
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    bad_boxed_value_cast(const std::string &val) throw()
 | 
			
		||||
      : m_val(val)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~bad_boxed_value_cast() throw()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual const char * what() const throw()
 | 
			
		||||
    {
 | 
			
		||||
      return m_val.c_str();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    std::string m_val;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs)
 | 
			
		||||
{
 | 
			
		||||
  if (lhs.is_unknown())
 | 
			
		||||
  {
 | 
			
		||||
    return (lhs.assign(rhs));
 | 
			
		||||
  } else {
 | 
			
		||||
    throw bad_boxed_value_cast("boxed_value has a set type alread");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//Built in to_string operator
 | 
			
		||||
template<typename Input>
 | 
			
		||||
std::string to_string(Input i)
 | 
			
		||||
{
 | 
			
		||||
  return boost::lexical_cast<std::string>(i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<> std::string to_string(bool b)
 | 
			
		||||
{
 | 
			
		||||
  if (b)
 | 
			
		||||
  {
 | 
			
		||||
    return "true";
 | 
			
		||||
  } else {
 | 
			
		||||
    return "false";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name)
 | 
			
		||||
{
 | 
			
		||||
  s.register_type<T>(name);
 | 
			
		||||
  add_basic_constructors<T>(s, name);
 | 
			
		||||
  add_oper_assign<T>(s);
 | 
			
		||||
  add_oper_assign_pod<T>(s);
 | 
			
		||||
  add_opers_arithmetic<T>(s);
 | 
			
		||||
  add_opers_arithmetic_modify_pod<T>(s);
 | 
			
		||||
  register_function(s, &to_string<T>, "to_string");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print(const std::string &s)
 | 
			
		||||
{
 | 
			
		||||
  std::cout << s << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bootstrap(Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  s.register_type<void>("void");
 | 
			
		||||
 | 
			
		||||
  s.register_type<std::string>("string");
 | 
			
		||||
 | 
			
		||||
  add_basic_constructors<bool>(s, "bool");
 | 
			
		||||
  add_basic_constructors<std::string>(s, "string");
 | 
			
		||||
  add_oper_assign<std::string>(s);
 | 
			
		||||
 | 
			
		||||
  register_function(s, &to_string<const std::string &>, "to_string");
 | 
			
		||||
  register_function(s, &to_string<bool>, "to_string");
 | 
			
		||||
  register_function(s, &unknown_assign, "=");
 | 
			
		||||
 | 
			
		||||
  bootstrap_pod_type<double>(s, "double");
 | 
			
		||||
  bootstrap_pod_type<int>(s, "int");
 | 
			
		||||
  bootstrap_pod_type<size_t>(s, "size_t");
 | 
			
		||||
  bootstrap_pod_type<char>(s, "char");
 | 
			
		||||
  bootstrap_pod_type<int64_t>(s, "int64_t");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  add_opers_comparison_pod(s);
 | 
			
		||||
  add_opers_arithmetic_pod(s);
 | 
			
		||||
 | 
			
		||||
  add_oper_add<std::string>(s);
 | 
			
		||||
  add_oper_add_equals <std::string>(s);
 | 
			
		||||
 | 
			
		||||
  register_function(s, &print, "print_string");
 | 
			
		||||
 | 
			
		||||
  s.register_function(boost::function<void ()>(boost::bind(&dump_system, boost::ref(s))), "dump_system");
 | 
			
		||||
  s.register_function(boost::function<void (Boxed_Value)>(boost::bind(&dump_object, _1)), "dump_object");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  register_function(s, &bool_and<bool, bool>, "&&");
 | 
			
		||||
  register_function(s, &bool_or<bool, bool>, "||");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
#ifndef __bootstrap_stl_hpp
 | 
			
		||||
#define __bootstrap_stl_hpp__
 | 
			
		||||
 | 
			
		||||
#include "boxedcpp.hpp"
 | 
			
		||||
 | 
			
		||||
template<typename ContainerType>
 | 
			
		||||
void bootstrap_reversible_container(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename ContainerType>
 | 
			
		||||
void bootstrap_random_access_container(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  bootstrap_reversible_container<ContainerType>(system, type);
 | 
			
		||||
 | 
			
		||||
  typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t);
 | 
			
		||||
 | 
			
		||||
  system.register_function(
 | 
			
		||||
      boost::function<typename ContainerType::reference (ContainerType *, int)>(indexoper(&ContainerType::at)), "[]");
 | 
			
		||||
  system.register_function(
 | 
			
		||||
      boost::function<typename ContainerType::reference (ContainerType *, int)>(indexoper(&ContainerType::operator[])), "at");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Assignable>
 | 
			
		||||
void bootstrap_assignable(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  system.register_function(
 | 
			
		||||
      boost::function<Assignable &(Assignable*, const Assignable&)>(&Assignable::operator=), "=");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename ContainerType>
 | 
			
		||||
void bootstrap_container(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  bootstrap_assignable<ContainerType>(system, type);
 | 
			
		||||
 | 
			
		||||
  system.register_function(
 | 
			
		||||
      boost::function<size_t (ContainerType *)>(&ContainerType::size), "size");
 | 
			
		||||
  system.register_function(
 | 
			
		||||
      boost::function<size_t (ContainerType *)>(&ContainerType::size), "maxsize");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename ContainerType>
 | 
			
		||||
void bootstrap_forward_container(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  bootstrap_container<ContainerType>(system, type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Type>
 | 
			
		||||
void bootstrap_default_constructible(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  system.register_function(build_constructor<Type>(), type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename SequenceType>
 | 
			
		||||
void bootstrap_sequence(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  bootstrap_forward_container<SequenceType>(system, type);
 | 
			
		||||
  bootstrap_default_constructible<SequenceType>(system, type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename SequenceType>
 | 
			
		||||
void bootstrap_back_insertion_sequence(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  bootstrap_sequence<SequenceType>(system, type);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  typedef typename SequenceType::reference (SequenceType::*backptr)();
 | 
			
		||||
 | 
			
		||||
  system.register_function(boost::function<typename SequenceType::reference (SequenceType *)>(backptr(&SequenceType::back)), "back");
 | 
			
		||||
  system.register_function(boost::function<void (SequenceType *,typename SequenceType::value_type)>(&SequenceType::push_back), "push_back");
 | 
			
		||||
  system.register_function(boost::function<void (SequenceType *)>(&SequenceType::pop_back), "pop_back");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename VectorType>
 | 
			
		||||
void bootstrap_vector(Dispatch_Engine &system, const std::string &type)
 | 
			
		||||
{
 | 
			
		||||
  system.register_type<VectorType>(type);
 | 
			
		||||
  bootstrap_random_access_container<VectorType>(system, type);
 | 
			
		||||
  bootstrap_back_insertion_sequence<VectorType>(system, type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,385 +0,0 @@
 | 
			
		||||
#ifndef __boxed_value_hpp__
 | 
			
		||||
#define __boxed_value_hpp__
 | 
			
		||||
 | 
			
		||||
#include "type_info.hpp"
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/any.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/ref.hpp>
 | 
			
		||||
 | 
			
		||||
class Boxed_Value
 | 
			
		||||
{
 | 
			
		||||
  private:
 | 
			
		||||
    struct Data
 | 
			
		||||
    {
 | 
			
		||||
      Data(const Type_Info &ti,
 | 
			
		||||
           const boost::any &to,
 | 
			
		||||
           bool tr)
 | 
			
		||||
        : m_type_info(ti), m_obj(to), m_is_ref(tr)
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      Data &operator=(const Data &rhs)
 | 
			
		||||
      {
 | 
			
		||||
        m_type_info = rhs.m_type_info;
 | 
			
		||||
        m_obj = rhs.m_obj;
 | 
			
		||||
        m_is_ref = rhs.m_is_ref;
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      Type_Info m_type_info;
 | 
			
		||||
      boost::any m_obj;
 | 
			
		||||
      bool m_is_ref;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
    struct Void_Type
 | 
			
		||||
    {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
      explicit Boxed_Value(boost::shared_ptr<T> obj)
 | 
			
		||||
       : m_data(new Data(
 | 
			
		||||
           Get_Type_Info<T>()(), 
 | 
			
		||||
           boost::any(obj), 
 | 
			
		||||
           false)
 | 
			
		||||
         )
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
      explicit Boxed_Value(boost::reference_wrapper<T> obj)
 | 
			
		||||
       : m_data(new Data(
 | 
			
		||||
             Get_Type_Info<T>()(),
 | 
			
		||||
             boost::any(obj), 
 | 
			
		||||
             true)
 | 
			
		||||
           )
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
      explicit Boxed_Value(const T& t)
 | 
			
		||||
       : m_data(new Data(
 | 
			
		||||
             Get_Type_Info<T>()(), 
 | 
			
		||||
             boost::any(boost::shared_ptr<T>(new T(t))), 
 | 
			
		||||
             false)
 | 
			
		||||
           )
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    Boxed_Value(Boxed_Value::Void_Type)
 | 
			
		||||
      : m_data(new Data(
 | 
			
		||||
            Get_Type_Info<void>()(),
 | 
			
		||||
            boost::any(), 
 | 
			
		||||
            false)
 | 
			
		||||
          )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Boxed_Value(const Boxed_Value &t_so)
 | 
			
		||||
      : m_data(t_so.m_data)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Boxed_Value()
 | 
			
		||||
      : m_data(new Data(
 | 
			
		||||
            Type_Info(),
 | 
			
		||||
            boost::any(),
 | 
			
		||||
            false)
 | 
			
		||||
          )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Boxed_Value assign(const Boxed_Value &rhs)
 | 
			
		||||
    {
 | 
			
		||||
      (*m_data) = (*rhs.m_data);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Boxed_Value &operator=(const Boxed_Value &rhs)
 | 
			
		||||
    {
 | 
			
		||||
      m_data = rhs.m_data;
 | 
			
		||||
      /*
 | 
			
		||||
      std::cout << "operator= called" << std::endl;
 | 
			
		||||
      m_data->m_obj = rhs.m_data->m_obj;
 | 
			
		||||
      m_data->m_type_info = rhs.m_data->m_type_info;
 | 
			
		||||
      m_data->m_is_ref = rhs.m_data->m_is_ref;
 | 
			
		||||
      (*m_data) = (*rhs.m_data);
 | 
			
		||||
      */
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const Type_Info &get_type_info() const
 | 
			
		||||
    {
 | 
			
		||||
      return m_data->m_type_info;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_unknown() const
 | 
			
		||||
    {
 | 
			
		||||
      return m_data->m_type_info.m_is_unknown;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    boost::any get() const
 | 
			
		||||
    {
 | 
			
		||||
      return m_data->m_obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_ref() const
 | 
			
		||||
    {
 | 
			
		||||
      return m_data->m_is_ref;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    boost::shared_ptr<Data> m_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//cast_help specializations
 | 
			
		||||
template<typename Result>
 | 
			
		||||
struct Cast_Helper
 | 
			
		||||
{
 | 
			
		||||
  typename boost::reference_wrapper<typename boost::add_const<Result>::type > operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    if (ob.is_ref())
 | 
			
		||||
    {
 | 
			
		||||
      return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
 | 
			
		||||
    } else {
 | 
			
		||||
      return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));   
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Result>
 | 
			
		||||
struct Cast_Helper<const Result &>
 | 
			
		||||
{
 | 
			
		||||
  typename boost::reference_wrapper<typename boost::add_const<Result>::type > operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    if (ob.is_ref())
 | 
			
		||||
    {
 | 
			
		||||
      return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
 | 
			
		||||
    } else {
 | 
			
		||||
      return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));   
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Result>
 | 
			
		||||
struct Cast_Helper<const Result *>
 | 
			
		||||
{
 | 
			
		||||
  const Result *operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    if (ob.is_ref())
 | 
			
		||||
    {
 | 
			
		||||
      return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
 | 
			
		||||
    } else {
 | 
			
		||||
      return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Result>
 | 
			
		||||
struct Cast_Helper<Result *>
 | 
			
		||||
{
 | 
			
		||||
  Result *operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    if (ob.is_ref())
 | 
			
		||||
    {
 | 
			
		||||
      return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
 | 
			
		||||
    } else {
 | 
			
		||||
      return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Result>
 | 
			
		||||
struct Cast_Helper<Result &>
 | 
			
		||||
{
 | 
			
		||||
  typename boost::reference_wrapper<Result> operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    if (ob.is_ref())
 | 
			
		||||
    {
 | 
			
		||||
      return boost::any_cast<boost::reference_wrapper<Result> >(ob.get());
 | 
			
		||||
    } else {
 | 
			
		||||
      return boost::ref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Result>
 | 
			
		||||
struct Cast_Helper<typename boost::shared_ptr<Result> >
 | 
			
		||||
{
 | 
			
		||||
  typename boost::shared_ptr<Result> operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    return boost::any_cast<boost::shared_ptr<Result> >(ob.get());
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
struct Cast_Helper<Boxed_Value>
 | 
			
		||||
{
 | 
			
		||||
  Boxed_Value operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    return ob;    
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct Boxed_POD_Value
 | 
			
		||||
{
 | 
			
		||||
  Boxed_POD_Value(const Boxed_Value &v)
 | 
			
		||||
    : d(0), i(0), m_isfloat(false)
 | 
			
		||||
  {
 | 
			
		||||
    const int inp_ = int(v.get_type_info().m_type_info);
 | 
			
		||||
 | 
			
		||||
    const int char_ = int(&typeid(char));
 | 
			
		||||
    const int bool_ = int(&typeid(bool));
 | 
			
		||||
 | 
			
		||||
    const int double_ = int(&typeid(double));
 | 
			
		||||
    const int float_ = int(&typeid(float));
 | 
			
		||||
 | 
			
		||||
    const int long_ = int(&typeid(long));
 | 
			
		||||
    const int unsigned_long_ = int(&typeid(unsigned long));
 | 
			
		||||
    const int int_ = int(&typeid(int));
 | 
			
		||||
    const int unsigned_int_ = int(&typeid(unsigned int));
 | 
			
		||||
 | 
			
		||||
    const int uint8_t_ = int(&typeid(uint8_t));
 | 
			
		||||
    const int uint16_t_ = int(&typeid(uint16_t));
 | 
			
		||||
    const int uint32_t_ = int(&typeid(uint32_t));
 | 
			
		||||
//    const int uint64_t_ = int(&typeid(uint64_t));
 | 
			
		||||
 | 
			
		||||
    const int int8_t_ = int(&typeid(int8_t));
 | 
			
		||||
    const int int16_t_ = int(&typeid(int16_t));
 | 
			
		||||
    const int int32_t_ = int(&typeid(int32_t));
 | 
			
		||||
    const int int64_t_ = int(&typeid(int64_t));
 | 
			
		||||
 | 
			
		||||
    if (inp_ == double_)
 | 
			
		||||
    {
 | 
			
		||||
      d = Cast_Helper<double>()(v);
 | 
			
		||||
      m_isfloat = true;
 | 
			
		||||
    } else if (inp_ == float_) {
 | 
			
		||||
      d = Cast_Helper<float>()(v);
 | 
			
		||||
      m_isfloat = true;
 | 
			
		||||
    } else if (inp_ == bool_ ) {
 | 
			
		||||
      i = Cast_Helper<bool>()(v);
 | 
			
		||||
    } else if (inp_ == char_) {
 | 
			
		||||
      i = Cast_Helper<char>()(v);
 | 
			
		||||
    } else if (inp_ == int_) {
 | 
			
		||||
      i = Cast_Helper<int>()(v);
 | 
			
		||||
    } else if (inp_ == unsigned_int_) {
 | 
			
		||||
      i = Cast_Helper<unsigned int>()(v);
 | 
			
		||||
    } else if (inp_ == long_) {
 | 
			
		||||
      i = Cast_Helper<long>()(v);
 | 
			
		||||
    } else if (inp_ == unsigned_long_) {
 | 
			
		||||
      i = Cast_Helper<unsigned long>()(v);
 | 
			
		||||
    } else if (inp_ == int8_t_) {
 | 
			
		||||
      i = Cast_Helper<int8_t>()(v);
 | 
			
		||||
    } else if (inp_ == int16_t_) {
 | 
			
		||||
      i = Cast_Helper<int16_t>()(v);
 | 
			
		||||
    } else if (inp_ == int32_t_) {
 | 
			
		||||
      i = Cast_Helper<int32_t>()(v);
 | 
			
		||||
    } else if (inp_ == int64_t_) {
 | 
			
		||||
      i = Cast_Helper<int64_t>()(v);
 | 
			
		||||
    } else if (inp_ == uint8_t_) {
 | 
			
		||||
      i = Cast_Helper<uint8_t>()(v);
 | 
			
		||||
    } else if (inp_ == uint16_t_) {
 | 
			
		||||
      i = Cast_Helper<uint16_t>()(v);
 | 
			
		||||
    } else if (inp_ == uint32_t_) {
 | 
			
		||||
      i = Cast_Helper<uint32_t>()(v);
 | 
			
		||||
    } else {
 | 
			
		||||
      throw boost::bad_any_cast();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  bool operator==(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator<(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    return ((m_isfloat)?d:i) < ((r.m_isfloat)?r.d:r.i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator>(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    return ((m_isfloat)?d:i) > ((r.m_isfloat)?r.d:r.i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator>=(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    return ((m_isfloat)?d:i) >= ((r.m_isfloat)?r.d:r.i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator<=(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    return ((m_isfloat)?d:i) <= ((r.m_isfloat)?r.d:r.i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator!=(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    return ((m_isfloat)?d:i) != ((r.m_isfloat)?r.d:r.i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Boxed_Value operator+(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    if (!m_isfloat && !r.m_isfloat)
 | 
			
		||||
    {
 | 
			
		||||
      return Boxed_Value(i + r.i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Boxed_Value operator*(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    if (!m_isfloat && !r.m_isfloat)
 | 
			
		||||
    {
 | 
			
		||||
      return Boxed_Value(i * r.i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Boxed_Value operator/(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    if (!m_isfloat && !r.m_isfloat)
 | 
			
		||||
    {
 | 
			
		||||
      return Boxed_Value(i / r.i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Boxed_Value operator-(const Boxed_POD_Value &r) const
 | 
			
		||||
  {
 | 
			
		||||
    if (!m_isfloat && !r.m_isfloat)
 | 
			
		||||
    {
 | 
			
		||||
      return Boxed_Value(i - r.i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  double d;
 | 
			
		||||
  int64_t i;
 | 
			
		||||
 | 
			
		||||
  bool m_isfloat;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
struct Cast_Helper<Boxed_POD_Value>
 | 
			
		||||
{
 | 
			
		||||
  Boxed_POD_Value operator()(Boxed_Value ob)
 | 
			
		||||
  {
 | 
			
		||||
    return Boxed_POD_Value(ob);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,209 +0,0 @@
 | 
			
		||||
#ifndef __boxedcpp_system_hpp__
 | 
			
		||||
#define __boxedcpp_system_hpp__
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/lexical_cast.hpp>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <deque>
 | 
			
		||||
 | 
			
		||||
#include "boxed_value.hpp"
 | 
			
		||||
#include "type_info.hpp"
 | 
			
		||||
#include "proxy_functions.hpp"
 | 
			
		||||
#include "proxy_constructors.hpp"
 | 
			
		||||
 | 
			
		||||
class Dispatch_Engine
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    typedef std::multimap<std::string, boost::shared_ptr<Proxy_Function> > Function_Map;
 | 
			
		||||
    typedef std::map<std::string, Type_Info> Type_Name_Map;
 | 
			
		||||
    typedef std::map<std::string, Boxed_Value> Scope;
 | 
			
		||||
    typedef std::deque<Scope> Stack;
 | 
			
		||||
 | 
			
		||||
    Dispatch_Engine()
 | 
			
		||||
    {
 | 
			
		||||
      m_scopes.push_back(Scope());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void register_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &name)
 | 
			
		||||
    {
 | 
			
		||||
      m_functions.insert(std::make_pair(name, f));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    template<typename Function>
 | 
			
		||||
      void register_function(const Function &func, const std::string &name)
 | 
			
		||||
      {
 | 
			
		||||
        m_functions.insert(std::make_pair(name, boost::shared_ptr<Proxy_Function>(new Proxy_Function_Impl<Function>(func))));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    template<typename Class>
 | 
			
		||||
      void set_object(const std::string &name, const Class &obj)
 | 
			
		||||
      {
 | 
			
		||||
        for (int i = m_scopes.size()-1; i >= 0; --i)
 | 
			
		||||
        {
 | 
			
		||||
          std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
 | 
			
		||||
          if (itr != m_scopes[i].end())
 | 
			
		||||
          {
 | 
			
		||||
            m_scopes[i][name] = Boxed_Value(obj);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        add_object(name, obj);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    template<typename Class>
 | 
			
		||||
      void add_object(const std::string &name, const Class &obj)
 | 
			
		||||
      {
 | 
			
		||||
        m_scopes.back()[name] = Boxed_Value(obj);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    void new_scope()
 | 
			
		||||
    {
 | 
			
		||||
      m_scopes.push_back(Scope());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void pop_scope()
 | 
			
		||||
    {
 | 
			
		||||
      if (m_scopes.size() > 1)
 | 
			
		||||
      {
 | 
			
		||||
        m_scopes.pop_back();
 | 
			
		||||
      } else {
 | 
			
		||||
        throw std::range_error("Unable to pop global stack");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Stack get_stack()
 | 
			
		||||
    {
 | 
			
		||||
      return m_scopes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Stack set_stack(Stack s)
 | 
			
		||||
    {
 | 
			
		||||
      swap(s, m_scopes);
 | 
			
		||||
      return s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Boxed_Value get_object(const std::string &name) const
 | 
			
		||||
    {
 | 
			
		||||
      for (int i = m_scopes.size()-1; i >= 0; --i)
 | 
			
		||||
      {
 | 
			
		||||
        std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
 | 
			
		||||
        if (itr != m_scopes[i].end())
 | 
			
		||||
        {
 | 
			
		||||
          return itr->second;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      throw std::range_error("Object not known: " + name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Type>
 | 
			
		||||
      void register_type(const std::string &name)
 | 
			
		||||
      {
 | 
			
		||||
        m_types.insert(std::make_pair(name, Get_Type_Info<Type>()()));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    std::vector<Type_Name_Map::value_type> get_types() const
 | 
			
		||||
    {
 | 
			
		||||
      return std::vector<Type_Name_Map::value_type>(m_types.begin(), m_types.end());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<std::pair<std::string, Function_Map::mapped_type> > 
 | 
			
		||||
      get_function(const std::string &t_name) const
 | 
			
		||||
    {
 | 
			
		||||
      std::vector<std::pair<std::string, Function_Map::mapped_type> > funcs;
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        funcs.insert(funcs.end(), 
 | 
			
		||||
            Function_Map::value_type(
 | 
			
		||||
              t_name, 
 | 
			
		||||
              Cast_Helper<Function_Map::mapped_type>()(get_object(t_name)))
 | 
			
		||||
            );
 | 
			
		||||
      } catch (const std::bad_cast &) {
 | 
			
		||||
      } catch (const std::range_error &) {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      std::pair<Function_Map::const_iterator, Function_Map::const_iterator> range
 | 
			
		||||
        = m_functions.equal_range(t_name);
 | 
			
		||||
 | 
			
		||||
      funcs.insert(funcs.end(), range.first, range.second);
 | 
			
		||||
      return funcs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<Function_Map::value_type> get_functions() const
 | 
			
		||||
    {
 | 
			
		||||
      return std::vector<Function_Map::value_type>(m_functions.begin(), m_functions.end());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    std::deque<Scope> m_scopes;
 | 
			
		||||
 | 
			
		||||
    Function_Map m_functions;
 | 
			
		||||
    Type_Name_Map m_types;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void dump_object(Boxed_Value o)
 | 
			
		||||
{
 | 
			
		||||
  std::cout << o.get_type_info().m_type_info->name() << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dump_type(const Type_Info &type)
 | 
			
		||||
{
 | 
			
		||||
  std::cout << type.m_bare_type_info->name();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dump_function(const Dispatch_Engine::Function_Map::value_type &f)
 | 
			
		||||
{
 | 
			
		||||
  std::vector<Type_Info> params = f.second->get_param_types();
 | 
			
		||||
 | 
			
		||||
  dump_type(params.front());
 | 
			
		||||
  std::cout << " " << f.first << "(";
 | 
			
		||||
 | 
			
		||||
  for (std::vector<Type_Info>::const_iterator itr = params.begin() + 1;
 | 
			
		||||
       itr != params.end();
 | 
			
		||||
       ++itr)
 | 
			
		||||
  {
 | 
			
		||||
    dump_type(*itr);
 | 
			
		||||
    std::cout << ", ";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::cout << ")" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dump_system(const Dispatch_Engine &s)
 | 
			
		||||
{
 | 
			
		||||
  std::cout << "Registered Types: " << std::endl;
 | 
			
		||||
  std::vector<Dispatch_Engine::Type_Name_Map::value_type> types = s.get_types();
 | 
			
		||||
  for (std::vector<Dispatch_Engine::Type_Name_Map::value_type>::const_iterator itr = types.begin();
 | 
			
		||||
       itr != types.end();
 | 
			
		||||
       ++itr)
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << itr->first << ": ";
 | 
			
		||||
    dump_type(itr->second);
 | 
			
		||||
    std::cout << std::endl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  std::cout << std::endl;  std::vector<Dispatch_Engine::Function_Map::value_type> funcs = s.get_functions();
 | 
			
		||||
 | 
			
		||||
  std::cout << "Functions: " << std::endl;
 | 
			
		||||
  for (std::vector<Dispatch_Engine::Function_Map::value_type>::const_iterator itr = funcs.begin();
 | 
			
		||||
       itr != funcs.end();
 | 
			
		||||
       ++itr)
 | 
			
		||||
  {
 | 
			
		||||
    dump_function(*itr);
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
#include <boost/preprocessor.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef  BOOST_PP_IS_ITERATING
 | 
			
		||||
#ifndef __proxy_constructors_hpp__
 | 
			
		||||
#define __proxy_constructors_hpp__
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/bind.hpp>
 | 
			
		||||
#include <boost/function.hpp>
 | 
			
		||||
 | 
			
		||||
template<typename Class>
 | 
			
		||||
boost::shared_ptr<Class> constructor()
 | 
			
		||||
{
 | 
			
		||||
  return boost::shared_ptr<Class>(new Class());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Class>
 | 
			
		||||
boost::function<boost::shared_ptr<Class> ()> build_constructor()
 | 
			
		||||
{
 | 
			
		||||
  typedef boost::shared_ptr<Class> (*func)();
 | 
			
		||||
  return boost::function<boost::shared_ptr<Class> ()>(func(&(constructor<Class>)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define BOOST_PP_ITERATION_LIMITS ( 1, 10 )
 | 
			
		||||
#define BOOST_PP_FILENAME_1 "proxy_constructors.hpp"
 | 
			
		||||
#include BOOST_PP_ITERATE()
 | 
			
		||||
# endif
 | 
			
		||||
#else
 | 
			
		||||
# define n BOOST_PP_ITERATION()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename Class, BOOST_PP_ENUM_PARAMS(n, typename Param) >
 | 
			
		||||
boost::shared_ptr<Class> constructor( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
 | 
			
		||||
{
 | 
			
		||||
  return boost::shared_ptr<Class>(new Class( BOOST_PP_ENUM_PARAMS(n, p) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Class, BOOST_PP_ENUM_PARAMS(n, typename Param) >
 | 
			
		||||
boost::function<boost::shared_ptr<Class> (BOOST_PP_ENUM_PARAMS(n, Param))> build_constructor()
 | 
			
		||||
{
 | 
			
		||||
  typedef boost::shared_ptr<Class> (*func)(BOOST_PP_ENUM_PARAMS(n, Param));
 | 
			
		||||
  return boost::function<boost::shared_ptr<Class> (BOOST_PP_ENUM_PARAMS(n, Param))>(func(&(constructor<Class, BOOST_PP_ENUM_PARAMS(n, Param)>)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,228 +0,0 @@
 | 
			
		||||
#include <boost/preprocessor.hpp>
 | 
			
		||||
 | 
			
		||||
#define gettypeinfo(z,n,text)  ti.push_back(Get_Type_Info<Param ## n>()());
 | 
			
		||||
#define casthelper(z,n,text) ,Cast_Helper<Param ## n>()(params[n])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef  BOOST_PP_IS_ITERATING
 | 
			
		||||
#ifndef __proxy_functions_hpp__
 | 
			
		||||
#define __proxy_functions_hpp__
 | 
			
		||||
 | 
			
		||||
#include "boxed_value.hpp"
 | 
			
		||||
#include "type_info.hpp"
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <boost/function.hpp>
 | 
			
		||||
#include <boost/bind.hpp>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
// handle_return implementations
 | 
			
		||||
template<typename Ret>
 | 
			
		||||
struct Handle_Return
 | 
			
		||||
{
 | 
			
		||||
  Boxed_Value operator()(const boost::function<Ret ()> &f)
 | 
			
		||||
  {
 | 
			
		||||
    return Boxed_Value(f());
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Ret>
 | 
			
		||||
struct Handle_Return<Ret &>
 | 
			
		||||
{
 | 
			
		||||
  Boxed_Value operator()(const boost::function<Ret &()> &f)
 | 
			
		||||
  {
 | 
			
		||||
    return Boxed_Value(boost::ref(f()));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
struct Handle_Return<Boxed_Value>
 | 
			
		||||
{
 | 
			
		||||
  Boxed_Value operator()(const boost::function<Boxed_Value ()> &f)
 | 
			
		||||
  {
 | 
			
		||||
    return f();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
struct Handle_Return<Boxed_Value &>
 | 
			
		||||
{
 | 
			
		||||
  Boxed_Value operator()(const boost::function<Boxed_Value &()> &f)
 | 
			
		||||
  {
 | 
			
		||||
    return f();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
struct Handle_Return<void>
 | 
			
		||||
{
 | 
			
		||||
  Boxed_Value operator()(const boost::function<void ()> &f)
 | 
			
		||||
  {
 | 
			
		||||
    f();
 | 
			
		||||
    return Boxed_Value(Boxed_Value::Void_Type());
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Build param type list (variadic)
 | 
			
		||||
template<typename Ret>
 | 
			
		||||
std::vector<Type_Info> build_param_type_list(const boost::function<Ret ()> &f)
 | 
			
		||||
{
 | 
			
		||||
  std::vector<Type_Info> ti;
 | 
			
		||||
  ti.push_back(Get_Type_Info<Ret>()());
 | 
			
		||||
  return ti;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// call_func implementations (variadic)
 | 
			
		||||
template<typename Ret>
 | 
			
		||||
Boxed_Value call_func(const boost::function<Ret ()> &f, const std::vector<Boxed_Value> ¶ms)
 | 
			
		||||
{
 | 
			
		||||
  if (params.size() != 0)
 | 
			
		||||
  {
 | 
			
		||||
    throw std::range_error("Incorrect number of parameters");
 | 
			
		||||
  } else {
 | 
			
		||||
    return Handle_Return<Ret>()(f);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Param_List_Builder
 | 
			
		||||
{
 | 
			
		||||
  Param_List_Builder &operator<<(const Boxed_Value &so)
 | 
			
		||||
  {
 | 
			
		||||
    objects.push_back(so);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
    Param_List_Builder &operator<<(T t)
 | 
			
		||||
    {
 | 
			
		||||
      objects.push_back(Boxed_Value(t));
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  operator const std::vector<Boxed_Value> &() const
 | 
			
		||||
  {
 | 
			
		||||
    return objects;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::vector<Boxed_Value> objects;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BOOST_PP_ITERATION_LIMITS ( 1, 10 )
 | 
			
		||||
#define BOOST_PP_FILENAME_1 "proxy_functions.hpp"
 | 
			
		||||
#include BOOST_PP_ITERATE()
 | 
			
		||||
 | 
			
		||||
class Proxy_Function
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    virtual ~Proxy_Function() {}
 | 
			
		||||
    virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) = 0;
 | 
			
		||||
    virtual std::vector<Type_Info> get_param_types() = 0;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Dynamic_Proxy_Function : public Proxy_Function
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    Dynamic_Proxy_Function(const boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> &t_f, int arity=-1)
 | 
			
		||||
      : m_f(t_f), m_arity(arity)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~Dynamic_Proxy_Function() {}
 | 
			
		||||
 | 
			
		||||
    virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
 | 
			
		||||
    {
 | 
			
		||||
      if (m_arity < 0 || params.size() == size_t(m_arity))
 | 
			
		||||
      {
 | 
			
		||||
        return m_f(params);
 | 
			
		||||
      } else {
 | 
			
		||||
        throw std::range_error("Incorrect number of parameters");
 | 
			
		||||
      } 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual std::vector<Type_Info> get_param_types()
 | 
			
		||||
    {
 | 
			
		||||
      return build_param_type_list(m_f);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> m_f;
 | 
			
		||||
    int m_arity;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename Func>
 | 
			
		||||
class Proxy_Function_Impl : public Proxy_Function
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    Proxy_Function_Impl(const Func &f)
 | 
			
		||||
      : m_f(f)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~Proxy_Function_Impl() {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
 | 
			
		||||
    {
 | 
			
		||||
      return call_func(m_f, params);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual std::vector<Type_Info> get_param_types()
 | 
			
		||||
    {
 | 
			
		||||
      return build_param_type_list(m_f);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    Func m_f;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Boxed_Value dispatch(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs,
 | 
			
		||||
  const std::vector<Boxed_Value> &plist)
 | 
			
		||||
{
 | 
			
		||||
  for (std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > >::const_iterator itr = funcs.begin();
 | 
			
		||||
       itr != funcs.end();
 | 
			
		||||
       ++itr)
 | 
			
		||||
  {
 | 
			
		||||
    try {
 | 
			
		||||
      return (*itr->second)(plist);
 | 
			
		||||
    } catch (const std::bad_cast &) {
 | 
			
		||||
      //try again
 | 
			
		||||
    } catch (const std::range_error &) {
 | 
			
		||||
      //invalid num params, try again
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  throw std::runtime_error("No matching function to dispatch to");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# endif
 | 
			
		||||
#else
 | 
			
		||||
# define n BOOST_PP_ITERATION()
 | 
			
		||||
 | 
			
		||||
template<typename Ret, BOOST_PP_ENUM_PARAMS(n, typename Param) >
 | 
			
		||||
std::vector<Type_Info> build_param_type_list(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f)
 | 
			
		||||
{
 | 
			
		||||
  std::vector<Type_Info> ti;
 | 
			
		||||
  ti.push_back(Get_Type_Info<Ret>()());
 | 
			
		||||
 | 
			
		||||
  BOOST_PP_REPEAT(n, gettypeinfo, ~)
 | 
			
		||||
 | 
			
		||||
  return ti;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Ret, BOOST_PP_ENUM_PARAMS(n, typename Param)>
 | 
			
		||||
Boxed_Value call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
 | 
			
		||||
    const std::vector<Boxed_Value> ¶ms)
 | 
			
		||||
{
 | 
			
		||||
  if (params.size() != n)
 | 
			
		||||
  {
 | 
			
		||||
    throw std::range_error("Incorrect number of parameters");
 | 
			
		||||
  } else {
 | 
			
		||||
    return Handle_Return<Ret>()(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~)));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
#include <boost/preprocessor.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef  BOOST_PP_IS_ITERATING
 | 
			
		||||
#ifndef __register_function_hpp__
 | 
			
		||||
#define __register_function_hpp__
 | 
			
		||||
 | 
			
		||||
#include <boxedcpp.hpp>
 | 
			
		||||
#include <boost/function.hpp>
 | 
			
		||||
#include <boost/bind.hpp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
 | 
			
		||||
#define BOOST_PP_FILENAME_1 "register_function.hpp"
 | 
			
		||||
 | 
			
		||||
#include BOOST_PP_ITERATE()
 | 
			
		||||
 | 
			
		||||
# endif
 | 
			
		||||
#else
 | 
			
		||||
# define n BOOST_PP_ITERATION()
 | 
			
		||||
 | 
			
		||||
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
 | 
			
		||||
void register_function(Dispatch_Engine &s, Ret (*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name)
 | 
			
		||||
{
 | 
			
		||||
  s.register_function(boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>(f), name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
 | 
			
		||||
void register_function(Dispatch_Engine &s, Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name)
 | 
			
		||||
{
 | 
			
		||||
  s.register_function(boost::function<Ret (Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f), name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,187 +0,0 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/function.hpp>
 | 
			
		||||
 | 
			
		||||
#include "boxedcpp.hpp"
 | 
			
		||||
#include "bootstrap.hpp"
 | 
			
		||||
#include "bootstrap_stl.hpp"
 | 
			
		||||
 | 
			
		||||
struct Test
 | 
			
		||||
{
 | 
			
		||||
  Test(const std::string &s)
 | 
			
		||||
    : message(s)
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << "Test class constructed with value: " << s << std::endl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void show_message()
 | 
			
		||||
  {
 | 
			
		||||
    std::cout << "Constructed Message: " << message << std::endl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::string &get_message()
 | 
			
		||||
  {
 | 
			
		||||
    return message;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::string message;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Boxed_Value named_func_call(Dispatch_Engine &ss,
 | 
			
		||||
    const std::string &nametocall, const std::vector<Boxed_Value> ¶ms)
 | 
			
		||||
{
 | 
			
		||||
  if (params.size() == 2)
 | 
			
		||||
  {
 | 
			
		||||
    return dispatch(ss.get_function(nametocall), params);
 | 
			
		||||
  } else {
 | 
			
		||||
    throw std::runtime_error("Invalid num params");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A function that takes a dynamic list of params
 | 
			
		||||
// and calls a bunch of conversion functions on them and 
 | 
			
		||||
// returns the result as a boxed_value
 | 
			
		||||
Boxed_Value dynamic_function(Dispatch_Engine &ss, const std::string &name, 
 | 
			
		||||
    const std::vector<Boxed_Value> ¶ms)
 | 
			
		||||
{
 | 
			
		||||
  if (name == "concat_string")
 | 
			
		||||
  {
 | 
			
		||||
    Boxed_Value result;
 | 
			
		||||
 | 
			
		||||
    //Return a void if there is nothing in the array
 | 
			
		||||
    if (params.size() == 0)
 | 
			
		||||
    {
 | 
			
		||||
      return result;
 | 
			
		||||
    } else {
 | 
			
		||||
      //else, prepopulate the result with a string conversion of the first
 | 
			
		||||
      //param
 | 
			
		||||
      result = 
 | 
			
		||||
        dispatch(ss.get_function("to_string"), Param_List_Builder() << params[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Then, loop over all remaining params, converting them to strings and adding
 | 
			
		||||
    //them to the result. This example maybe bette served with a string += operator
 | 
			
		||||
    //implementation, but it works.
 | 
			
		||||
    for (size_t i = 1; i < params.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
      result = 
 | 
			
		||||
        dispatch(ss.get_function("+"), Param_List_Builder() << result << 
 | 
			
		||||
            dispatch(ss.get_function("to_string"), Param_List_Builder() << params[i]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
  } else {
 | 
			
		||||
    throw std::runtime_error("Unknown function call");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test(const std::string &p)
 | 
			
		||||
{
 | 
			
		||||
  std::cout << "Test: " << p << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//Test main
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  Dispatch_Engine ss;
 | 
			
		||||
  bootstrap(ss);
 | 
			
		||||
  bootstrap_vector<std::vector<int> >(ss, "VectorInt");
 | 
			
		||||
  dump_system(ss);
 | 
			
		||||
 | 
			
		||||
  //Calling a function by name and allowing the built in dispatch mechanism to
 | 
			
		||||
  //choose the most appropriate version of the function
 | 
			
		||||
  Boxed_Value addresult = dispatch(ss.get_function("+"), Param_List_Builder() << double(5.1) << double(10.3));
 | 
			
		||||
 | 
			
		||||
  //Using the Cast_Helper to unbox the resultant value and output it
 | 
			
		||||
  std::cout << Cast_Helper<double>()(addresult) << std::endl;
 | 
			
		||||
 | 
			
		||||
  //Using the Boxed_Value as input to another function, again with automatic dispatch.
 | 
			
		||||
  //This time we will not bother saving the result and will instead send it straight out
 | 
			
		||||
  std::cout << Cast_Helper<double>()(
 | 
			
		||||
      dispatch(ss.get_function("*"), Param_List_Builder() << 2 << addresult)
 | 
			
		||||
      ) << std::endl;
 | 
			
		||||
 | 
			
		||||
  //Register a new function, this one with typing for us, so we don't have to ubox anything
 | 
			
		||||
  //right here
 | 
			
		||||
 | 
			
		||||
  //Now we have a print method, let's try to print out the earlier example:
 | 
			
		||||
  //so, we dispatch the to_string and pass its result as a param to "print"
 | 
			
		||||
  //In this example we don't bother with temporaries and we don't have to know
 | 
			
		||||
  //anything about types
 | 
			
		||||
  dispatch(ss.get_function("print"),
 | 
			
		||||
      Param_List_Builder() << dispatch(ss.get_function("to_string"), Param_List_Builder() << addresult));
 | 
			
		||||
 | 
			
		||||
  // Now we are going to register a new dynamic function,
 | 
			
		||||
  // when this function is called the objects are not unboxed, but passed
 | 
			
		||||
  // in in their boxed state
 | 
			
		||||
  ss.register_function(boost::shared_ptr<Proxy_Function>(new Dynamic_Proxy_Function(boost::bind(&dynamic_function, boost::ref(ss), "concat_string", _1))), "concat_string");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Call our newly defined dynamic function with 10 parameters, then send
 | 
			
		||||
  // its output to the "print" function
 | 
			
		||||
  dispatch(ss.get_function("print"),
 | 
			
		||||
      Param_List_Builder() << dispatch(ss.get_function("concat_string"),
 | 
			
		||||
        Param_List_Builder() << std::string("\n\t") << std::string("The Value Was: ") 
 | 
			
		||||
                             << double(42.5) << std::string(".")
 | 
			
		||||
                             << '\n'
 | 
			
		||||
                             << '\t' << std::string("The old value was: ")
 | 
			
		||||
                             << addresult << '.' << '\n' ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  //Register some local methods of the "Test" class
 | 
			
		||||
  ss.register_function(build_constructor<Test, const std::string &>(), "Test");
 | 
			
		||||
 | 
			
		||||
  register_function(ss, &Test::get_message, "get_message");
 | 
			
		||||
  register_function(ss, &Test::show_message, "show_message");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  //Create a new object using the "Test" constructor, passing the param "Yo".
 | 
			
		||||
  //Then, add the new object to the system with the name "testobj2"
 | 
			
		||||
  ss.add_object("testobj2", 
 | 
			
		||||
      dispatch(ss.get_function("Test"), Param_List_Builder() << std::string("Yo")));
 | 
			
		||||
 | 
			
		||||
  // Look up and store a reference to our new object
 | 
			
		||||
  std::vector<Boxed_Value> sos;
 | 
			
		||||
  sos.push_back(ss.get_object("testobj2"));
 | 
			
		||||
 | 
			
		||||
  //Print the message the object was created with
 | 
			
		||||
  dispatch(ss.get_function("show_message"), sos);
 | 
			
		||||
 | 
			
		||||
  //Now, get a reference to the object's stored message
 | 
			
		||||
  Boxed_Value stringref = dispatch(ss.get_function("get_message"), sos);
 | 
			
		||||
 | 
			
		||||
  //Unbox it using Cast_Helper
 | 
			
		||||
  std::string &sr = Cast_Helper<std::string &>()(stringref);
 | 
			
		||||
 | 
			
		||||
  //Update the value of the reference
 | 
			
		||||
  sr = "Bob Updated The message";
 | 
			
		||||
 | 
			
		||||
  //Now, prove that the reference was successfully acquired
 | 
			
		||||
  //and we are able to peek into the boxed types
 | 
			
		||||
  dispatch(ss.get_function("show_message"), sos);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Finally, we are going to register some named function aliases, for 
 | 
			
		||||
  // the fun of it
 | 
			
		||||
  ss.register_function(boost::shared_ptr<Proxy_Function>(
 | 
			
		||||
        new Dynamic_Proxy_Function(boost::bind(&named_func_call, boost::ref(ss), "+", _1))), "add");
 | 
			
		||||
 | 
			
		||||
  //Call our newly named "add" function (which in turn dispatches +)
 | 
			
		||||
  
 | 
			
		||||
  std::cout << "Result of add function: " << 
 | 
			
		||||
    Cast_Helper<int>()(dispatch(ss.get_function("add"), Param_List_Builder() << 5 << 2))
 | 
			
		||||
    << std::endl; 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  ss.set_object("myfunc", boost::shared_ptr<Proxy_Function>(new Proxy_Function_Impl<boost::function<void (const std::string &)> >(&test)));
 | 
			
		||||
 | 
			
		||||
  dispatch(ss.get_function("myfunc"), Param_List_Builder() << std::string("hello function variable"));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,80 +0,0 @@
 | 
			
		||||
#ifndef __type_info_hpp__
 | 
			
		||||
#define __type_info_hpp__
 | 
			
		||||
 | 
			
		||||
#include <boost/type_traits.hpp>
 | 
			
		||||
#include <boost/ref.hpp>
 | 
			
		||||
struct Type_Info
 | 
			
		||||
{
 | 
			
		||||
  Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, 
 | 
			
		||||
      const std::type_info *t_ti, const std::type_info *t_bareti)
 | 
			
		||||
    : m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
 | 
			
		||||
      m_type_info(t_ti), m_bare_type_info(t_bareti),
 | 
			
		||||
      m_is_unknown(false)
 | 
			
		||||
  {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Type_Info()
 | 
			
		||||
    : m_is_const(false), m_is_reference(false), m_is_pointer(false),
 | 
			
		||||
      m_is_void(false), m_type_info(0), m_bare_type_info(0),
 | 
			
		||||
      m_is_unknown(true)
 | 
			
		||||
  {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Type_Info &operator=(const Type_Info &ti)
 | 
			
		||||
  {
 | 
			
		||||
    m_is_const = ti.m_is_const;
 | 
			
		||||
    m_is_reference = ti.m_is_reference;
 | 
			
		||||
    m_is_pointer = ti.m_is_pointer;
 | 
			
		||||
    m_is_void = ti.m_is_void;
 | 
			
		||||
    m_type_info = ti.m_type_info;
 | 
			
		||||
    m_bare_type_info = ti.m_bare_type_info;
 | 
			
		||||
    m_is_unknown = ti.m_is_unknown;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool m_is_const;
 | 
			
		||||
  bool m_is_reference;
 | 
			
		||||
  bool m_is_pointer;
 | 
			
		||||
  bool m_is_void;
 | 
			
		||||
  const std::type_info *m_type_info;
 | 
			
		||||
  const std::type_info *m_bare_type_info;
 | 
			
		||||
  bool m_is_unknown;
 | 
			
		||||
 };
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct Get_Type_Info
 | 
			
		||||
{
 | 
			
		||||
  Type_Info operator()()
 | 
			
		||||
  {
 | 
			
		||||
    return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value, 
 | 
			
		||||
        boost::is_void<T>::value,
 | 
			
		||||
        &typeid(T), 
 | 
			
		||||
        &typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct Get_Type_Info<boost::shared_ptr<T> >
 | 
			
		||||
{
 | 
			
		||||
  Type_Info operator()()
 | 
			
		||||
  {
 | 
			
		||||
    return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value, 
 | 
			
		||||
        boost::is_void<T>::value,
 | 
			
		||||
        &typeid(boost::shared_ptr<T> ), 
 | 
			
		||||
        &typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct Get_Type_Info<boost::reference_wrapper<T> >
 | 
			
		||||
{
 | 
			
		||||
  Type_Info operator()()
 | 
			
		||||
  {
 | 
			
		||||
    return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value, 
 | 
			
		||||
        boost::is_void<T>::value,
 | 
			
		||||
        &typeid(boost::reference_wrapper<T> ), 
 | 
			
		||||
        &typeid(typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
#include "boxedcpp.hpp"
 | 
			
		||||
#include "bootstrap.hpp"
 | 
			
		||||
 | 
			
		||||
#define BOOST_TEST_DYN_LINK
 | 
			
		||||
#define BOOST_TEST_MODULE boxedcpp_unittests
 | 
			
		||||
#include <boost/test/unit_test.hpp>
 | 
			
		||||
 | 
			
		||||
BOOST_AUTO_TEST_CASE( add_operators )
 | 
			
		||||
{
 | 
			
		||||
  Dispatch_Engine ss;
 | 
			
		||||
  bootstrap(ss);
 | 
			
		||||
  dump_system(ss);
 | 
			
		||||
 | 
			
		||||
  BOOST_CHECK_EQUAL(Cast_Helper<int>()(dispatch(ss.get_function("+"), Param_List_Builder() << double(5.1) << double(10.3))), 15.4);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user