Work around bug in g++4.6
I'm going to have to start dropping support for older compilers soon. The 4.6 line is 4 years old now, and 4.7 has these issues fixed
This commit is contained in:
		@@ -35,6 +35,10 @@
 | 
			
		||||
#define CHAISCRIPT_HAS_THREAD_LOCAL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 | 
			
		||||
#define CHAISCRIPT_GCC_4_6
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || defined(CHAISCRIPT_MSVC) || defined(__llvm__)
 | 
			
		||||
#define CHAISCRIPT_OVERRIDE override
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,113 @@ namespace chaiscript
 | 
			
		||||
  {
 | 
			
		||||
    namespace detail
 | 
			
		||||
    {
 | 
			
		||||
      /**
 | 
			
		||||
       * Used by Proxy_Function_Impl to return a list of all param types
 | 
			
		||||
       * it contains.
 | 
			
		||||
       */
 | 
			
		||||
      template<typename Ret, typename ... Params>
 | 
			
		||||
        std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
 | 
			
		||||
        {
 | 
			
		||||
          /// \note somehow this is responsible for a large part of the code generation
 | 
			
		||||
          return { user_type<Ret>(), user_type<Params>()... };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef CHAISCRIPT_GCC_4_6 
 | 
			
		||||
      /// \todo REMOVE THIS WHEN WE DROP G++4.6
 | 
			
		||||
      
 | 
			
		||||
      // Forward declaration
 | 
			
		||||
      template<typename ... Rest> 
 | 
			
		||||
        struct Try_Cast; 
 | 
			
		||||
 | 
			
		||||
      template<typename Param, typename ... Rest>
 | 
			
		||||
        struct Try_Cast<Param, Rest...>
 | 
			
		||||
        {
 | 
			
		||||
          static void do_try(const std::vector<Boxed_Value> ¶ms, size_t generation, const Type_Conversions &t_conversions)
 | 
			
		||||
          {
 | 
			
		||||
            boxed_cast<Param>(params[generation], &t_conversions);
 | 
			
		||||
            Try_Cast<Rest...>::do_try(params, generation+1, t_conversions);
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
      // 0th case
 | 
			
		||||
      template<>
 | 
			
		||||
        struct Try_Cast<>
 | 
			
		||||
        {
 | 
			
		||||
          static void do_try(const std::vector<Boxed_Value> &, size_t, const Type_Conversions &)
 | 
			
		||||
          {
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Used by Proxy_Function_Impl to determine if it is equivalent to another
 | 
			
		||||
       * Proxy_Function_Impl object. This function is primarily used to prevent
 | 
			
		||||
       * registration of two functions with the exact same signatures
 | 
			
		||||
       */
 | 
			
		||||
      template<typename Ret, typename ... Params>
 | 
			
		||||
        bool compare_types_cast(Ret (*)(Params...),
 | 
			
		||||
             const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
 | 
			
		||||
       {
 | 
			
		||||
          try {
 | 
			
		||||
            Try_Cast<Params...>::do_try(params, 0, t_conversions);
 | 
			
		||||
          } catch (const exception::bad_boxed_cast &) {
 | 
			
		||||
            return false;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      template<typename Ret, int count, typename ... Params>
 | 
			
		||||
        struct Call_Func
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
          template<typename ... InnerParams>
 | 
			
		||||
          static Ret do_call(const std::function<Ret (Params...)> &f,
 | 
			
		||||
              const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
 | 
			
		||||
          {
 | 
			
		||||
            return Call_Func<Ret, count - 1, Params...>::do_call(f, params, t_conversions, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
 | 
			
		||||
          } 
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
      template<typename Ret, typename ... Params>
 | 
			
		||||
        struct Call_Func<Ret, 0, Params...>
 | 
			
		||||
        {
 | 
			
		||||
#ifdef CHAISCRIPT_MSVC
 | 
			
		||||
#pragma warning(push)
 | 
			
		||||
#pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this
 | 
			
		||||
#endif
 | 
			
		||||
          template<typename ... InnerParams>
 | 
			
		||||
            static Ret do_call(const std::function<Ret (Params...)> &f,
 | 
			
		||||
                const std::vector<Boxed_Value> &, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
 | 
			
		||||
            {
 | 
			
		||||
              return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
 | 
			
		||||
            }
 | 
			
		||||
#ifdef CHAISCRIPT_MSVC
 | 
			
		||||
#pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Used by Proxy_Function_Impl to perform typesafe execution of a function.
 | 
			
		||||
       * The function attempts to unbox each parameter to the expected type.
 | 
			
		||||
       * if any unboxing fails the execution of the function fails and
 | 
			
		||||
       * the bad_boxed_cast is passed up to the caller.
 | 
			
		||||
       */
 | 
			
		||||
      template<typename Ret, typename ... Params>
 | 
			
		||||
        Ret call_func(const std::function<Ret (Params...)> &f,
 | 
			
		||||
            const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
 | 
			
		||||
        {
 | 
			
		||||
          if (params.size() == sizeof...(Params))
 | 
			
		||||
          {
 | 
			
		||||
            return Call_Func<Ret, sizeof...(Params), Params...>::do_call(f, params, t_conversions);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
      template<size_t ... I>
 | 
			
		||||
      struct Indexes
 | 
			
		||||
      {
 | 
			
		||||
@@ -70,16 +177,6 @@ namespace chaiscript
 | 
			
		||||
        typedef Indexes<I...> indexes;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Used by Proxy_Function_Impl to return a list of all param types
 | 
			
		||||
       * it contains.
 | 
			
		||||
       */
 | 
			
		||||
      template<typename Ret, typename ... Params>
 | 
			
		||||
        std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
 | 
			
		||||
        {
 | 
			
		||||
          /// \note somehow this is responsible for a large part of the code generation
 | 
			
		||||
          return { user_type<Ret>(), user_type<Params>()... };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
@@ -135,6 +232,8 @@ namespace chaiscript
 | 
			
		||||
          throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user