Roll back changes from last 2 checkins - user defined type conversions are going to be too slow and too hard to keep track of. Need more portable / generic approach to solving the actual problem - the ability to deal with inhertance properly
This commit is contained in:
parent
3d19138c95
commit
f7086c10ec
@ -101,11 +101,6 @@ IF(BUILD_TESTING)
|
|||||||
target_link_libraries(utility_test ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB})
|
target_link_libraries(utility_test ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB})
|
||||||
add_test(NAME Utility_Test COMMAND utility_test)
|
add_test(NAME Utility_Test COMMAND utility_test)
|
||||||
|
|
||||||
|
|
||||||
add_executable(inheritance_test unittests/inheritance_test.cpp)
|
|
||||||
target_link_libraries(inheritance_test ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB})
|
|
||||||
add_test(NAME Inheritance_Test COMMAND inheritance_test)
|
|
||||||
|
|
||||||
ENDIF(BUILD_TESTING)
|
ENDIF(BUILD_TESTING)
|
||||||
|
|
||||||
install(TARGETS chai stl_extra test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript )
|
install(TARGETS chai stl_extra test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript )
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include "boxed_value.hpp"
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
#include "type_conversion.hpp"
|
|
||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
#include "proxy_constructors.hpp"
|
#include "proxy_constructors.hpp"
|
||||||
#include "dynamic_object.hpp"
|
#include "dynamic_object.hpp"
|
||||||
@ -44,11 +43,6 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Module &add(const Type_Conversion &tc)
|
|
||||||
{
|
|
||||||
m_conversions.push_back(tc);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add a bit of chaiscript to eval during module implementation
|
//Add a bit of chaiscript to eval during module implementation
|
||||||
Module &eval(const std::string &str)
|
Module &eval(const std::string &str)
|
||||||
@ -68,14 +62,12 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
apply(m_typeinfos.begin(), m_typeinfos.end(), t_engine);
|
apply(m_typeinfos.begin(), m_typeinfos.end(), t_engine);
|
||||||
apply(m_funcs.begin(), m_funcs.end(), t_engine);
|
apply(m_funcs.begin(), m_funcs.end(), t_engine);
|
||||||
apply_nameless(m_conversions.begin(), m_conversions.end(), t_engine);
|
|
||||||
apply_eval(m_evals.begin(), m_evals.end(), t_eval);
|
apply_eval(m_evals.begin(), m_evals.end(), t_eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::pair<Type_Info, std::string> > m_typeinfos;
|
std::vector<std::pair<Type_Info, std::string> > m_typeinfos;
|
||||||
std::vector<std::pair<Proxy_Function, std::string> > m_funcs;
|
std::vector<std::pair<Proxy_Function, std::string> > m_funcs;
|
||||||
std::vector<Type_Conversion> m_conversions;
|
|
||||||
std::vector<std::string> m_evals;
|
std::vector<std::string> m_evals;
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
template<typename T, typename InItr>
|
||||||
@ -88,16 +80,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
|
||||||
void apply_nameless(InItr begin, InItr end, T &t) const
|
|
||||||
{
|
|
||||||
while (begin != end)
|
|
||||||
{
|
|
||||||
t.add(*begin);
|
|
||||||
++begin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
template<typename T, typename InItr>
|
||||||
void apply_eval(InItr begin, InItr end, T &t) const
|
void apply_eval(InItr begin, InItr end, T &t) const
|
||||||
{
|
{
|
||||||
@ -220,7 +202,6 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
std::multimap<std::string, Proxy_Function> m_functions;
|
std::multimap<std::string, Proxy_Function> m_functions;
|
||||||
std::map<std::string, Boxed_Value> m_global_objects;
|
std::map<std::string, Boxed_Value> m_global_objects;
|
||||||
Type_Converter m_type_converter;
|
|
||||||
Type_Name_Map m_types;
|
Type_Name_Map m_types;
|
||||||
std::set<std::string> m_reserved_words;
|
std::set<std::string> m_reserved_words;
|
||||||
};
|
};
|
||||||
@ -249,19 +230,6 @@ namespace chaiscript
|
|||||||
return add_function(f, name);
|
return add_function(f, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new type converter to the system
|
|
||||||
*/
|
|
||||||
void add(const Type_Conversion &tc)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
|
||||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_state.m_type_converter.add(tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of an object, by name. If the object
|
* Set the value of an object, by name. If the object
|
||||||
* is not available in the current scope it is created
|
* is not available in the current scope it is created
|
||||||
|
@ -1,218 +0,0 @@
|
|||||||
#ifndef __CHAISCRIPT_DISPATCH_TYPE_CONVERSION_HPP__
|
|
||||||
#define __CHAISCRIPT_DISPATCH_TYPE_CONVERSION_HPP__
|
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
|
||||||
#include "type_info.hpp"
|
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
|
||||||
#include <boost/type_traits/remove_const.hpp>
|
|
||||||
#include <boost/type_traits/remove_pointer.hpp>
|
|
||||||
#include <boost/type_traits/add_const.hpp>
|
|
||||||
|
|
||||||
namespace chaiscript
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
class Type_Conversion_Impl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~Type_Conversion_Impl()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual Boxed_Value convert(const Boxed_Value &v) const = 0;
|
|
||||||
|
|
||||||
Type_Info from() const
|
|
||||||
{
|
|
||||||
return m_from;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type_Info to() const
|
|
||||||
{
|
|
||||||
return m_to;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Type_Conversion_Impl(const Type_Info &t_from, const Type_Info &t_to)
|
|
||||||
: m_from(t_from), m_to(t_to)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Type_Info m_from;
|
|
||||||
Type_Info m_to;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename From, typename To>
|
|
||||||
class Dynamic_Cast_Conversion : public Type_Conversion_Impl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef From From_Type;
|
|
||||||
typedef To To_Type;
|
|
||||||
|
|
||||||
Dynamic_Cast_Conversion()
|
|
||||||
: Type_Conversion_Impl(user_type<From_Type>(), user_type<To_Type>())
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual ~Dynamic_Cast_Conversion()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual Boxed_Value convert(const Boxed_Value &v) const
|
|
||||||
{
|
|
||||||
if (v.is_pointer())
|
|
||||||
{
|
|
||||||
if (v.is_const())
|
|
||||||
{
|
|
||||||
return const_pointer_convert(v);
|
|
||||||
} else {
|
|
||||||
return pointer_convert(v);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (v.is_const())
|
|
||||||
{
|
|
||||||
return const_reference_convert(v);
|
|
||||||
} else {
|
|
||||||
return reference_convert(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Boxed_Value pointer_convert(const Boxed_Value &v) const
|
|
||||||
{
|
|
||||||
boost::shared_ptr<To_Type> to =
|
|
||||||
boost::dynamic_pointer_cast<To_Type>(boxed_cast<boost::shared_ptr<From_Type> >(v));
|
|
||||||
|
|
||||||
if (to) {
|
|
||||||
return Boxed_Value(to);
|
|
||||||
} else {
|
|
||||||
throw bad_boxed_cast(v.get_type_info(), typeid(To_Type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Value const_pointer_convert(const Boxed_Value &v) const
|
|
||||||
{
|
|
||||||
boost::shared_ptr<typename boost::add_const<To_Type>::type> to =
|
|
||||||
boost::dynamic_pointer_cast<typename boost::add_const<To_Type>::type>(boxed_cast<boost::shared_ptr<typename boost::add_const<From_Type>::type> >(v));
|
|
||||||
|
|
||||||
if (to) {
|
|
||||||
return Boxed_Value(to);
|
|
||||||
} else {
|
|
||||||
throw bad_boxed_cast(v.get_type_info(), typeid(To_Type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Value reference_convert(const Boxed_Value &v) const
|
|
||||||
{
|
|
||||||
To_Type *to =
|
|
||||||
dynamic_cast<To_Type *>(boxed_cast<From_Type *>(v));
|
|
||||||
|
|
||||||
if (to) {
|
|
||||||
return Boxed_Value(to);
|
|
||||||
} else {
|
|
||||||
throw bad_boxed_cast(v.get_type_info(), typeid(To_Type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Value const_reference_convert(const Boxed_Value &v) const
|
|
||||||
{
|
|
||||||
typename boost::add_const<To_Type>::type *to =
|
|
||||||
dynamic_cast<typename boost::add_const<To_Type>::type *>(boxed_cast<typename boost::add_const<From_Type>::type *>(v));
|
|
||||||
|
|
||||||
if (to) {
|
|
||||||
return Boxed_Value(to);
|
|
||||||
} else {
|
|
||||||
throw bad_boxed_cast(v.get_type_info(), typeid(To_Type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Type_Conversion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Type_Conversion(const boost::shared_ptr<detail::Type_Conversion_Impl> t_impl)
|
|
||||||
: m_impl(t_impl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Value convert(const Boxed_Value &v) const
|
|
||||||
{
|
|
||||||
return m_impl->convert(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type_Info from() const
|
|
||||||
{
|
|
||||||
return m_impl->from();
|
|
||||||
}
|
|
||||||
|
|
||||||
Type_Info to() const
|
|
||||||
{
|
|
||||||
return m_impl->to();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
boost::shared_ptr<detail::Type_Conversion_Impl> m_impl;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename From, typename To>
|
|
||||||
Type_Conversion dynamic_cast_conversion()
|
|
||||||
{
|
|
||||||
typedef typename boost::remove_const<
|
|
||||||
typename boost::remove_pointer<
|
|
||||||
typename boost::remove_reference<From>::type>::type>::type Cleaned_From;
|
|
||||||
|
|
||||||
typedef typename boost::remove_const<
|
|
||||||
typename boost::remove_pointer<
|
|
||||||
typename boost::remove_reference<To>::type>::type>::type Cleaned_To;
|
|
||||||
|
|
||||||
return Type_Conversion(boost::shared_ptr<detail::Type_Conversion_Impl>(new detail::Dynamic_Cast_Conversion<Cleaned_From, Cleaned_To>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
class Type_Converter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool add(const Type_Conversion &t_tc)
|
|
||||||
{
|
|
||||||
return m_conversions.insert(std::make_pair(std::make_pair(t_tc.from(), t_tc.to()), t_tc)).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty()
|
|
||||||
{
|
|
||||||
return m_conversions.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Value convert(const Boxed_Value &t_bv, const Type_Info &t_to) const
|
|
||||||
{
|
|
||||||
if (t_bv.get_type_info().bare_equal(t_to))
|
|
||||||
{
|
|
||||||
return t_bv;
|
|
||||||
} else {
|
|
||||||
std::map<std::pair<Type_Info, Type_Info>, Type_Conversion>::const_iterator itr = m_conversions.begin(),
|
|
||||||
end = m_conversions.end();
|
|
||||||
|
|
||||||
while (itr != end)
|
|
||||||
{
|
|
||||||
if (itr->first.first.bare_equal(t_bv.get_type_info())
|
|
||||||
&& itr->first.second.bare_equal(t_to))
|
|
||||||
{
|
|
||||||
return itr->second.convert(t_bv);
|
|
||||||
}
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw bad_boxed_cast("Unable to convert boxed_value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<std::pair<Type_Info, Type_Info>, Type_Conversion> m_conversions;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
|||||||
#include <chaiscript/utility/utility.hpp>
|
|
||||||
|
|
||||||
class Test
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string function() { return "Function"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Test2 : public Test
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string function2() { return "Function2"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
|
|
||||||
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
|
|
||||||
|
|
||||||
CHAISCRIPT_CLASS( m,
|
|
||||||
Test,
|
|
||||||
(Test ())
|
|
||||||
(Test (const Test &)),
|
|
||||||
((function))
|
|
||||||
);
|
|
||||||
|
|
||||||
CHAISCRIPT_CLASS( m,
|
|
||||||
Test2,
|
|
||||||
(Test2 ())
|
|
||||||
(Test2 (const Test2 &)),
|
|
||||||
((function2))
|
|
||||||
);
|
|
||||||
|
|
||||||
chaiscript::ChaiScript chai;
|
|
||||||
|
|
||||||
m->add(chaiscript::dynamic_cast_conversion<Test2, Test>());
|
|
||||||
|
|
||||||
|
|
||||||
chai.add(m);
|
|
||||||
if (chai.eval<std::string>("var t = Test2(); t.function(); ") == "Function"
|
|
||||||
&& chai.eval<std::string>("var t = Test2(); t.function2(); ") == "Function2")
|
|
||||||
{
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
} else {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user