Exemple #1
0
    decltype(auto) boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr) {
        if (!t_conversions || bv.get_type_info().bare_equal(user_type<Type>()) || (t_conversions && !(*t_conversions)->convertable_type<Type>())) {
            try {
                return (detail::Cast_Helper<Type>::cast(bv, t_conversions));
            } catch (const chaiscript::detail::exception::bad_any_cast &) {
            }
        }


        if (t_conversions && (*t_conversions)->convertable_type<Type>()) {
            try {
                // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
                // either way, we are not responsible if it doesn't work
                return (detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_conversion<Type>(t_conversions->saves(), bv), t_conversions));
            } catch (...) {
                try {
                    // try going the other way
                    return (detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_down_conversion<Type>(t_conversions->saves(), bv), t_conversions));
                } catch (const chaiscript::detail::exception::bad_any_cast &) {
                    throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
                }
            }
        } else {
            // If it's not convertable, just throw the error, don't waste the time on the
            // attempted dynamic_cast
            throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
        }

    }
  typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr)
  {
    if (!t_conversions || bv.get_type_info().bare_equal(user_type<Type>()) || (t_conversions && !(*t_conversions)->convertable_type<Type>())) {
      try {
        return detail::Cast_Helper<Type>::cast(bv, t_conversions);
      } catch (const chaiscript::detail::exception::bad_any_cast &) {
      }
    }


    if (t_conversions && (*t_conversions)->convertable_type<Type>())
    {
      try {
        // std::cout << "trying an up conversion " << typeid(Type).name() << '\n';
        // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
        // either way, we are not responsible if it doesn't work
        return detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_conversion<Type>(t_conversions->saves(), bv), t_conversions);
      } catch (...) {
        try {
        //  std::cout << "trying a down conversion " << typeid(Type).name() << '\n';
          // try going the other way - down the inheritance graph
          return detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_down_conversion<Type>(t_conversions->saves(), bv), t_conversions);
        } catch (const chaiscript::detail::exception::bad_any_cast &) {
          throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
        }
      }
    } else {
      // If it's not polymorphic, just throw the error, don't waste the time on the 
      // attempted dynamic_cast
      throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
    }

  }
Exemple #3
0
  typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv)
  {
    try {
      return detail::Cast_Helper<Type>::cast(bv);
    } catch (const boost::bad_any_cast &) {

#ifdef BOOST_MSVC
      //Thank you MSVC, yes we know that a constant value is being used in the if
      // statment in THIS VERSION of the template instantiation
#pragma warning(push)
#pragma warning(disable : 4127)
#endif

      if (boost::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value)
      {
        try {
          // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
          // either way, we are not responsible if it doesn't work
          return detail::Cast_Helper<Type>::cast(detail::boxed_dynamic_cast<Type>(bv));
        } catch (const boost::bad_any_cast &) {
          throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
        }
      } else {
        // If it's not polymorphic, just throw the error, don't waste the time on the 
        // attempted dynamic_cast
        throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
      }

#ifdef BOOST_MSVC
#pragma warning(pop)
#endif


    } 
  }
 static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
 {
   if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result))
   {
     return static_cast<Result *>(throw_if_null(ob.get_ptr()));
   } else {
     throw chaiscript::detail::exception::bad_any_cast();
   }
 }
 Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived) const
 {
     try {
         return get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
     } catch (const std::out_of_range &) {
         throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion");
     } catch (const std::bad_cast &) {
         throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation");
     }
 }
          static Boxed_Value cast(const Boxed_Value &t_from)
          {
            if (t_from.get_type_info().bare_equal(user_type<From>()))
            {
              if (t_from.is_pointer())
              {
                // Dynamic cast out the contained boxed value, which we know is the type we want
                if (t_from.is_const())
                {
                  std::shared_ptr<const To> data
                    = std::dynamic_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr));
                  if (!data)
                  {
                    throw std::bad_cast();
                  }

                  return Boxed_Value(data);
                } else {
                  std::shared_ptr<To> data
                    = std::dynamic_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr));

                  if (!data)
                  {
                    throw std::bad_cast();
                  }

                  return Boxed_Value(data);
                }
              } else {
                // Pull the reference out of the contained boxed value, which we know is the type we want
                if (t_from.is_const())
                {
                  const From &d = detail::Cast_Helper<const From &>::cast(t_from, nullptr);
                  const To &data = dynamic_cast<const To &>(d);
                  return Boxed_Value(std::cref(data));
                } else {
                  From &d = detail::Cast_Helper<From &>::cast(t_from, nullptr);
                  To &data = dynamic_cast<To &>(d);
                  return Boxed_Value(std::ref(data));
                }
              }
            } else {
              throw chaiscript::exception::bad_boxed_dynamic_cast(t_from.get_type_info(), typeid(To), "Unknown dynamic_cast_conversion");
            }
          }
    virtual Boxed_Value convert(const Boxed_Value &t_derived) const
    {
        if (t_derived.get_type_info().bare_equal(user_type<Derived>()))
        {
            if (t_derived.is_pointer())
            {
                // Dynamic cast out the contained boxed value, which we know is the type we want
                if (t_derived.is_const())
                {
                    boost::shared_ptr<const Base> data
                        = boost::dynamic_pointer_cast<const Base>(detail::Cast_Helper<boost::shared_ptr<const Derived> >::cast(t_derived, 0));
                    if (!data)
                    {
                        throw std::bad_cast();
                    }

                    return Boxed_Value(data);
                } else {
                    boost::shared_ptr<Base> data
                        = boost::dynamic_pointer_cast<Base>(detail::Cast_Helper<boost::shared_ptr<Derived> >::cast(t_derived, 0));

                    if (!data)
                    {
                        throw std::bad_cast();
                    }

                    return Boxed_Value(data);
                }
            } else {
                // Pull the reference out of the contained boxed value, which we know is the type we want
                if (t_derived.is_const())
                {
                    const Derived &d = detail::Cast_Helper<const Derived &>::cast(t_derived, 0);
                    const Base &data = dynamic_cast<const Base &>(d);
                    return Boxed_Value(boost::cref(data));
                } else {
                    Derived &d = detail::Cast_Helper<Derived &>::cast(t_derived, 0);
                    Base &data = dynamic_cast<Base &>(d);
                    return Boxed_Value(boost::ref(data));
                }
            }
        } else {
            throw exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
        }
    }
 static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
 {
   if (!ob.get_type_info().is_const())
   {
     return std::const_pointer_cast<const Result>(ob.get().cast<std::shared_ptr<Result> >());
   } else {
     return ob.get().cast<std::shared_ptr<const Result> >();
   }
 }
 static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions &t_conversions)
 {
   if (ti.is_undef() 
       || ti.bare_equal(user_type<Boxed_Value>())
       || (!bv.get_type_info().is_undef()
         && (ti.bare_equal(user_type<Boxed_Number>())
           || ti.bare_equal(bv.get_type_info())
           || bv.get_type_info().bare_equal(user_type<std::shared_ptr<const Proxy_Function_Base> >())
           || t_conversions.converts(ti, bv.get_type_info()) 
           )
         )
      )
   {
     return true;
   } else {
     return false;
   }
 }
 static Result_Type cast(const Boxed_Value &ob)
 {
   if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
   {
     return dispatch::functor<Signature>(ob);
   } else {
     return Cast_Helper_Inner<const boost::function<Signature> &>::cast(ob);
   }
 }
 static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
 {
   if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
   {
     auto p = throw_if_null(ob.get_const_ptr());
     return std::cref(*static_cast<const Result *>(p));
   } else {
     throw chaiscript::detail::exception::bad_any_cast();
   }
 }
 static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
 {
   if (ob.is_ref())
   {
     if (!ob.get_type_info().is_const())
     {
       return &(ob.get().cast<std::reference_wrapper<Result> >()).get();
     } else {
       return &(ob.get().cast<std::reference_wrapper<const Result> >()).get();
     }
   } else {
     if (!ob.get_type_info().is_const())
     {
       return (ob.get().cast<std::shared_ptr<Result> >()).get();
     } else {
       return (ob.get().cast<std::shared_ptr<const Result> >()).get();
     }
   }
 }
  typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions *t_conversions = nullptr)
  {
    try {
      return detail::Cast_Helper<Type>::cast(bv, t_conversions);
    } catch (const chaiscript::detail::exception::bad_any_cast &) {


#ifdef CHAISCRIPT_MSVC
      //Thank you MSVC, yes we know that a constant value is being used in the if
      // statment in THIS VERSION of the template instantiation
#pragma warning(push)
#pragma warning(disable : 4127)
#endif

      if (t_conversions && t_conversions->convertable_type<Type>())
      {
        try {
          // std::cout << "trying an up conversion " << typeid(Type).name() << '\n';
          // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
          // either way, we are not responsible if it doesn't work
          return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_conversion<Type>(bv), t_conversions);
        } catch (...) {
          try {
          //  std::cout << "trying a down conversion " << typeid(Type).name() << '\n';
            // try going the other way - down the inheritance graph
            return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_down_conversion<Type>(bv), t_conversions);
          } catch (const chaiscript::detail::exception::bad_any_cast &) {
            throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
          }
        }
      } else {
        // If it's not polymorphic, just throw the error, don't waste the time on the 
        // attempted dynamic_cast
        throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
      }

#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif


    } 
  }
          bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name,
              const std::unique_ptr<Type_Info> &ti, const Type_Conversions &t_conversions) const
          {
            if (bv.get_type_info().bare_equal(m_doti))
            {
              try {
                const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bv, &t_conversions);
                return name == "Dynamic_Object" || d.get_type_name() == name;
              } catch (const std::bad_cast &) {
                return false;
              } 
            } else {
              if (ti)
              {
                return bv.get_type_info().bare_equal(*ti);
              } else {
                return false;
              }
            }

          }
Exemple #15
0
      static Common_Types get_common_type(const Boxed_Value &t_bv)
      {
        const Type_Info &inp_ = t_bv.get_type_info();

        if (inp_ == typeid(int)) {
          return get_common_type(sizeof(int), true);
        } else if (inp_ == typeid(double)) {
          return Common_Types::t_double;
        } else if (inp_ == typeid(long double)) {
          return Common_Types::t_long_double;
        } else if (inp_ == typeid(float)) {
          return Common_Types::t_float;
        } else if (inp_ == typeid(char)) {
          return get_common_type(sizeof(char), std::is_signed<char>::value);
        } else if (inp_ == typeid(unsigned char)) {
          return get_common_type(sizeof(unsigned char), false);
        } else if (inp_ == typeid(unsigned int)) {
          return get_common_type(sizeof(unsigned int), false);
        } else if (inp_ == typeid(long)) {
          return get_common_type(sizeof(long), true);
        } else if (inp_ == typeid(long long)) {
          return get_common_type(sizeof(long long), true);
        } else if (inp_ == typeid(unsigned long)) {
          return get_common_type(sizeof(unsigned long), false);
        } else if (inp_ == typeid(unsigned long long)) {
          return get_common_type(sizeof(unsigned long long), false);
        } else if (inp_ == typeid(std::int8_t)) {
          return Common_Types::t_int8;
        } else if (inp_ == typeid(std::int16_t)) {
          return Common_Types::t_int16;
        } else if (inp_ == typeid(std::int32_t)) {
          return Common_Types::t_int32;
        } else if (inp_ == typeid(std::int64_t)) {
          return Common_Types::t_int64;
        } else if (inp_ == typeid(std::uint8_t)) {
          return Common_Types::t_uint8;
        } else if (inp_ == typeid(std::uint16_t)) {
          return Common_Types::t_uint16;
        } else if (inp_ == typeid(std::uint32_t)) {
          return Common_Types::t_uint32;
        } else if (inp_ == typeid(std::uint64_t)) {
          return Common_Types::t_uint64;
        } else if (inp_ == typeid(wchar_t)) {
          return get_common_type(sizeof(wchar_t), std::is_signed<wchar_t>::value);
        } else if (inp_ == typeid(char16_t)) {
          return get_common_type(sizeof(char16_t), std::is_signed<char16_t>::value);
        } else if (inp_ == typeid(char32_t)) {
          return get_common_type(sizeof(char32_t), std::is_signed<char32_t>::value);
        } else  {
          throw chaiscript::detail::exception::bad_any_cast();
        }
      }
          static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name,
              const boost::optional<Type_Info> &ti)
          {
            static Type_Info doti = user_type<Dynamic_Object>();
            if (bv.get_type_info().bare_equal(doti))
            {
              try {
                const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bv);
                return name == "Dynamic_Object" || d.get_type_name() == name;
              } catch (const std::bad_cast &) {
                return false;
              } 
            } else {
              if (ti)
              {
                return bv.get_type_info().bare_equal(*ti);
              } else {
                return false;
              }
            }

          }
bool test_type_conversion(const Boxed_Value &bv, bool expectedpass)
{
  bool ret = run_test_type_conversion<To>(bv, expectedpass);

  if (!ret)
  {
    std::cerr << "Error with type conversion test. From: " 
		<< (bv.is_const()?(std::string("const ")):(std::string())) << bv.get_type_info().name() 
		<< " To: "  
		<< (std::is_const<To>::value?(std::string("const ")):(std::string())) << typeid(To).name() 
      << " test was expected to " << ((expectedpass)?(std::string("succeed")):(std::string("fail"))) << " but did not" << std::endl;
  }

  return ret;
}