Make Type_Info internal data private and provide more rigorous definitions for comparisions of objects

This commit is contained in:
Jason Turner
2009-09-08 13:31:14 +00:00
parent 73ec2abd43
commit b185e2e792
5 changed files with 104 additions and 88 deletions

View File

@@ -181,7 +181,7 @@ namespace chaiscript
// Both t and t.x share the same memory location, but do not represent // Both t and t.x share the same memory location, but do not represent
// objects of the same type. // objects of the same type.
if (itr != m_ptrs.end() if (itr != m_ptrs.end()
&& type_info_bare_equals(itr->second.m_type_info, data->m_type_info)) && itr->second.m_type_info.bare_equal(data->m_type_info))
{ {
(*data) = (itr->second); (*data) = (itr->second);
} }
@@ -321,7 +321,7 @@ namespace chaiscript
*/ */
bool is_unknown() const bool is_unknown() const
{ {
return m_data->m_type_info.m_is_unknown; return m_data->m_type_info.is_unknown();
} }
boost::any get() const boost::any get() const
@@ -355,14 +355,14 @@ namespace chaiscript
{ {
if (ob.is_ref()) if (ob.is_ref())
{ {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get()); return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
} else { } else {
return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get()); return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get());
} }
} else { } else {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get()))); return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
} else { } else {
@@ -384,14 +384,14 @@ namespace chaiscript
{ {
if (ob.is_ref()) if (ob.is_ref())
{ {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get()); return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
} else { } else {
return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get()); return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get());
} }
} else { } else {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get()))); return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
} else { } else {
@@ -413,14 +413,14 @@ namespace chaiscript
{ {
if (ob.is_ref()) if (ob.is_ref())
{ {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer(); return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
} else { } else {
return (boost::any_cast<boost::reference_wrapper<const Result> >(ob.get())).get_pointer(); return (boost::any_cast<boost::reference_wrapper<const Result> >(ob.get())).get_pointer();
} }
} else { } else {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get(); return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
} else { } else {
@@ -492,7 +492,7 @@ namespace chaiscript
static Result_Type cast(const Boxed_Value &ob) static Result_Type cast(const Boxed_Value &ob)
{ {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return boost::const_pointer_cast<const Result>(boost::any_cast<boost::shared_ptr<Result> >(ob.get())); return boost::const_pointer_cast<const Result>(boost::any_cast<boost::shared_ptr<Result> >(ob.get()));
} else { } else {
@@ -525,7 +525,7 @@ namespace chaiscript
static Result_Type cast(const Boxed_Value &ob) static Result_Type cast(const Boxed_Value &ob)
{ {
if (!ob.get_type_info().m_is_const) if (!ob.get_type_info().is_const())
{ {
return boost::const_pointer_cast<const Result>(boost::any_cast<boost::shared_ptr<Result> >(ob.get())); return boost::const_pointer_cast<const Result>(boost::any_cast<boost::shared_ptr<Result> >(ob.get()));
} else { } else {
@@ -573,7 +573,7 @@ namespace chaiscript
{ {
public: public:
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.m_type_info), to(&t_to), m_what("Cannot perform boxed_cast") : from(t_from), to(&t_to), m_what("Cannot perform boxed_cast")
{ {
} }
@@ -588,7 +588,8 @@ namespace chaiscript
{ {
return m_what.c_str(); return m_what.c_str();
} }
const std::type_info *from;
Type_Info from;
const std::type_info *to; const std::type_info *to;
private: private:
@@ -619,12 +620,12 @@ namespace chaiscript
Boxed_POD_Value(const Boxed_Value &v) Boxed_POD_Value(const Boxed_Value &v)
: d(0), i(0), m_isfloat(false) : d(0), i(0), m_isfloat(false)
{ {
if (!v.get_type_info().m_type_info) if (v.get_type_info().is_unknown())
{ {
throw boost::bad_any_cast(); throw boost::bad_any_cast();
} }
const std::type_info &inp_ = *v.get_type_info().m_type_info; const Type_Info &inp_ = v.get_type_info();
if (inp_ == typeid(double)) if (inp_ == typeid(double))
{ {

View File

@@ -416,13 +416,13 @@ namespace chaiscript
itr != m_types.end(); itr != m_types.end();
++itr) ++itr)
{ {
if (type_info_bare_equals(itr->second, ti)) if (itr->second.bare_equal(ti))
{ {
return itr->first; return itr->first;
} }
} }
return ti.m_bare_type_info->name(); return ti.bare_name();
} }
/** /**
@@ -581,7 +581,7 @@ namespace chaiscript
void dump_object(Boxed_Value o, const Dispatch_Engine &e) void dump_object(Boxed_Value o, const Dispatch_Engine &e)
{ {
Type_Info ti = o.get_type_info(); Type_Info ti = o.get_type_info();
std::cout << (ti.m_is_const?"const ":"") << e.get_type_name(ti) << std::endl; std::cout << (ti.is_const()?"const ":"") << e.get_type_name(ti) << std::endl;
} }
/** /**
@@ -589,7 +589,7 @@ namespace chaiscript
*/ */
void dump_type(const Type_Info &type, const Dispatch_Engine &e) void dump_type(const Type_Info &type, const Dispatch_Engine &e)
{ {
std::cout << (type.m_is_const?"const ":"") << e.get_type_name(type); std::cout << (type.is_const()?"const ":"") << e.get_type_name(type);
} }
/** /**
@@ -634,7 +634,7 @@ namespace chaiscript
++itr) ++itr)
{ {
std::cout << itr->first << ": "; std::cout << itr->first << ": ";
std::cout << itr->second.m_bare_type_info->name(); std::cout << itr->second.bare_name();
std::cout << std::endl; std::cout << std::endl;
} }

View File

@@ -91,10 +91,10 @@ namespace chaiscript
const Type_Info &ti = types[1]; const Type_Info &ti = types[1];
if (!ti.m_bare_type_info || !(vals[0].get_type_info().m_bare_type_info) if (ti.is_unknown() || vals[0].get_type_info().is_unknown()
|| type_info_bare_equals(ti, user_type<Boxed_Value>()) || ti.bare_equal(user_type<Boxed_Value>())
|| type_info_bare_equals(ti, user_type<Boxed_POD_Value>()) || ti.bare_equal(user_type<Boxed_POD_Value>())
|| type_info_bare_equals(vals[0].get_type_info(), ti)) || ti.bare_equal(vals[0].get_type_info()))
{ {
return true; return true;
} else { } else {

View File

@@ -21,61 +21,91 @@ namespace chaiscript
/** /**
* compile time deduced information about a type * compile time deduced information about a type
*/ */
struct Type_Info class Type_Info
{ {
Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, public:
const std::type_info *t_ti, const std::type_info *t_bareti) Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
: m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer), 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_is_void(t_is_void), m_is_void(t_is_void),
m_type_info(t_ti), m_bare_type_info(t_bareti), m_type_info(t_ti), m_bare_type_info(t_bareti),
m_is_unknown(false) m_is_unknown(false)
{ {
} }
Type_Info() Type_Info()
: m_is_const(false), m_is_reference(false), m_is_pointer(false), : 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_void(false), m_type_info(0), m_bare_type_info(0),
m_is_unknown(true) m_is_unknown(true)
{ {
} }
Type_Info(const Type_Info &ti) Type_Info(const Type_Info &ti)
: m_is_const(ti.m_is_const), m_is_reference(ti.m_is_reference), : m_is_const(ti.m_is_const), m_is_reference(ti.m_is_reference),
m_is_pointer(ti.m_is_pointer), m_is_pointer(ti.m_is_pointer),
m_is_void(ti.m_is_void), m_type_info(ti.m_type_info), m_is_void(ti.m_is_void), m_type_info(ti.m_type_info),
m_bare_type_info(ti.m_bare_type_info), m_bare_type_info(ti.m_bare_type_info),
m_is_unknown(ti.m_is_unknown) m_is_unknown(ti.m_is_unknown)
{ {
} }
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 operator<(const Type_Info &ti) const
{
return m_type_info < ti.m_type_info;
}
bool operator==(const Type_Info &ti) const Type_Info &operator=(const Type_Info &ti)
{ {
return ti.m_type_info == m_type_info m_is_const = ti.m_is_const;
|| (ti.m_type_info && m_type_info && *ti.m_type_info == *m_type_info); 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 operator<(const Type_Info &ti) const
bool m_is_reference; {
bool m_is_pointer; return m_type_info < ti.m_type_info;
bool m_is_void; }
const std::type_info *m_type_info;
const std::type_info *m_bare_type_info; bool operator==(const Type_Info &ti) const
bool m_is_unknown; {
return ti.m_type_info == m_type_info
|| (ti.m_type_info && m_type_info && *ti.m_type_info == *m_type_info);
}
bool operator==(const std::type_info &ti) const
{
return m_type_info != 0 && (*m_type_info) == ti;
}
bool bare_equal(const Type_Info &ti) const
{
return ti.m_bare_type_info == m_bare_type_info
|| (ti.m_bare_type_info && m_bare_type_info && *ti.m_bare_type_info == *m_bare_type_info);
}
bool is_const() const { return m_is_const; }
bool is_reference() const { return m_is_reference; }
bool is_void() const { return m_is_void; }
bool is_unknown() const { return m_is_unknown || m_bare_type_info == 0; }
std::string bare_name() const
{
if (m_bare_type_info)
{
return m_bare_type_info->name();
} else {
return "";
}
}
private:
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;
}; };
namespace detail namespace detail
@@ -145,21 +175,6 @@ namespace chaiscript
return detail::Get_Type_Info<T>::get(); return detail::Get_Type_Info<T>::get();
} }
bool type_info_bare_equals(const Type_Info &l, const Type_Info &r)
{
if (l.m_bare_type_info == 0
&& r.m_bare_type_info == 0)
{
return true;
} else if (l.m_bare_type_info == 0
|| r.m_bare_type_info == 0)
{
return false;
} else {
return *(l.m_bare_type_info) == *(r.m_bare_type_info);
}
}
} }
#endif #endif

View File

@@ -62,7 +62,7 @@ int main(int argc, char *argv[]) {
val = chai.eval(input); val = chai.eval(input);
//Then, we try to print the result of the evaluation to the user //Then, we try to print the result of the evaluation to the user
if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) { if (val.get_type_info().bare_equal(chaiscript::user_type<void>())) {
try { try {
chaiscript::dispatch(chai.get_eval_engine().get_function("print"), chaiscript::Param_List_Builder() << val); chaiscript::dispatch(chai.get_eval_engine().get_function("print"), chaiscript::Param_List_Builder() << val);
} }