Merge pull request #172 from ChaiScript/libcxx_ubuntu_14_04
Libcxx ubuntu 14 04
This commit is contained in:
		| @@ -15,6 +15,12 @@ | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #if defined( _LIBCPP_VERSION ) | ||||
| #define CHAISCRIPT_LIBCPP | ||||
| #endif | ||||
|  | ||||
| #if defined(_WIN32) || defined(__CYGWIN__) | ||||
| #define CHAISCRIPT_WINDOWS | ||||
| #endif | ||||
|   | ||||
| @@ -14,63 +14,58 @@ namespace chaiscript | ||||
|   namespace detail | ||||
|   { | ||||
|  | ||||
|     struct Placeholder | ||||
|     { | ||||
|       static std::tuple<decltype(std::placeholders::_1),decltype(std::placeholders::_2),decltype(std::placeholders::_3),decltype(std::placeholders::_4),decltype(std::placeholders::_5),decltype(std::placeholders::_6),decltype(std::placeholders::_7),decltype(std::placeholders::_8),decltype(std::placeholders::_9),decltype(std::placeholders::_10)> placeholder() { | ||||
|         return std::tuple<decltype(std::placeholders::_1),decltype(std::placeholders::_2),decltype(std::placeholders::_3),decltype(std::placeholders::_4),decltype(std::placeholders::_5),decltype(std::placeholders::_6),decltype(std::placeholders::_7),decltype(std::placeholders::_8),decltype(std::placeholders::_9),decltype(std::placeholders::_10)>(std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5,std::placeholders::_6,std::placeholders::_7,std::placeholders::_8,std::placeholders::_9,std::placeholders::_10); | ||||
|     template<typename T> | ||||
|       T* get_pointer(T *t) | ||||
|       { | ||||
|         return t; | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|     template<int count, int maxcount, typename Sig> | ||||
|       struct Bind_First | ||||
|     template<typename T> | ||||
|       T* get_pointer(const std::reference_wrapper<T> &t) | ||||
|       { | ||||
|         template<typename F, typename ... InnerParams> | ||||
|           static std::function<Sig> bind(F&& f, InnerParams ... innerparams) | ||||
|           { | ||||
|             return Bind_First<count - 1, maxcount, Sig>::bind(std::forward<F>(f), innerparams..., std::get<maxcount - count>(Placeholder::placeholder())); | ||||
|           }  | ||||
|       }; | ||||
|  | ||||
|     template<int maxcount, typename Sig> | ||||
|       struct Bind_First<0, maxcount, Sig> | ||||
|       { | ||||
|         template<typename F, typename ... InnerParams> | ||||
|           static std::function<Sig> bind(F&& f, InnerParams ... innerparams) | ||||
|           { | ||||
|     return std::bind(std::forward<F>(f), innerparams...); | ||||
|           } | ||||
|       }; | ||||
|  | ||||
|         return &t.get(); | ||||
|       } | ||||
|  | ||||
|     template<typename O, typename Ret, typename P1, typename ... Param> | ||||
|       std::function<Ret (Param...)> bind_first(Ret (*f)(P1, Param...), O&& o) | ||||
|       { | ||||
|         return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, std::forward<O>(o)); | ||||
|         return std::function<Ret (Param...)>( | ||||
|             [f, o](Param...param) -> Ret { | ||||
|               return f(std::forward<O>(o), std::forward<Param>(param)...); | ||||
|             } | ||||
|           ); | ||||
|       } | ||||
|  | ||||
|     template<typename O, typename Ret, typename Class, typename ... Param> | ||||
|       std::function<Ret (Param...)> bind_first(Ret (Class::*f)(Param...), O&& o) | ||||
|       { | ||||
|         return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, std::forward<O>(o)); | ||||
|         return std::function<Ret (Param...)>( | ||||
|             [f, o](Param...param) -> Ret { | ||||
|               return (get_pointer(o)->*f)(std::forward<Param>(param)...); | ||||
|             } | ||||
|           ); | ||||
|       } | ||||
|  | ||||
|     template<typename O, typename Ret, typename Class, typename ... Param> | ||||
|       std::function<Ret (Param...)> bind_first(Ret (Class::*f)(Param...) const, O&& o) | ||||
|       { | ||||
|         return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, std::forward<O>(o)); | ||||
|         return std::function<Ret (Param...)>( | ||||
|             [f, o](Param...param) -> Ret { | ||||
|               return (get_pointer(o)->*f)(std::forward<Param>(param)...); | ||||
|             } | ||||
|           ); | ||||
|  | ||||
|       } | ||||
|  | ||||
|     template<typename O, typename Ret, typename P1, typename ... Param> | ||||
|       std::function<Ret (Param...)> bind_first(const std::function<Ret (P1, Param...)> &f, O&& o) | ||||
|       { | ||||
|         return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, std::forward<O>(o)); | ||||
|         return std::function<Ret (Param...)>( | ||||
|             [f, o](Param...param) -> Ret { | ||||
|               return f(o, std::forward<Param>(param)...); | ||||
|             }); | ||||
|       } | ||||
|  | ||||
|     template<typename O, typename Ret, typename P1, typename ... Param> | ||||
|       std::function<Ret (Param...)> bind_first(std::function<Ret (P1, Param...)> &&f, O&& o) | ||||
|       { | ||||
|         return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(std::move(f), std::forward<O>(o)); | ||||
|       } | ||||
|  | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -394,7 +394,9 @@ namespace chaiscript | ||||
|       template<typename Function> | ||||
|       static std::function<std::vector<Boxed_Value> (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f) | ||||
|       { | ||||
|         return std::bind(&do_return_boxed_value_vector<Function>, f, std::placeholders::_1); | ||||
|         return [f](const dispatch::Proxy_Function_Base *b) { | ||||
|           return do_return_boxed_value_vector(f, b); | ||||
|         }; | ||||
|       } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -247,7 +247,6 @@ namespace chaiscript | ||||
|         { | ||||
|           // cppcheck-suppress syntaxError | ||||
|           typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); | ||||
|           typedef typename ContainerType::const_reference(ContainerType::*constindexoper)(size_t) const; | ||||
|  | ||||
|           //In the interest of runtime safety for the m, we prefer the at() method for [] access, | ||||
|           //to throw an exception in an out of bounds condition. | ||||
| @@ -255,8 +254,10 @@ namespace chaiscript | ||||
|               fun(std::function<typename ContainerType::reference (ContainerType *, int)> | ||||
|                 (std::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]"); | ||||
|           m->add( | ||||
|               fun(std::function<typename ContainerType::const_reference (const ContainerType *, int)> | ||||
|                 (std::mem_fn(static_cast<constindexoper>(&ContainerType::at)))), "[]"); | ||||
|               fun<typename ContainerType::const_reference (const ContainerType *, int)>( | ||||
|                 [](const ContainerType *c, int index) -> typename ContainerType::const_reference { | ||||
|                   return c->at(index); | ||||
|                 }), "[]"); | ||||
|  | ||||
|           return m; | ||||
|         } | ||||
|   | ||||
| @@ -52,36 +52,17 @@ namespace chaiscript | ||||
|       template<typename Ret, typename Class, typename ... Args>  | ||||
|         std::function<Ret (const Class &, Args...) > to_function(Ret (Class::*func)(Args...) const) | ||||
|         { | ||||
| #ifdef CHAISCRIPT_MSVC | ||||
| #if defined(CHAISCRIPT_MSVC) || defined(CHAISCRIPT_LIBCPP) | ||||
|           /// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for  | ||||
|           ///       std::function for member function pointers seems to be broken in MSVC | ||||
|           return std::function<Ret(const Class &, Args...)>(std::mem_fn(func)); | ||||
|           return std::function<Ret (const Class &, Args...)>([func](const Class &o, Args... args)->Ret { | ||||
|                 return (o.*func)(std::forward<Args>(args)...); | ||||
|               }); | ||||
| #else | ||||
|           return std::function<Ret(const Class &, Args...)>(func); | ||||
| #endif | ||||
|         } | ||||
|  | ||||
|       template<bool Object> | ||||
|         struct Fun_Helper | ||||
|         { | ||||
|           template<typename T> | ||||
|             static Proxy_Function go(T t) | ||||
|             { | ||||
|               /// \todo is it possible to reduce the number of templates generated here? | ||||
|               return Proxy_Function( | ||||
|                   static_cast<dispatch::Proxy_Function_Impl_Base *>(new Proxy_Function_Impl<typename FunctionSignature<decltype(to_function(t)) >::Signature>(to_function(t)))); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|       template<> | ||||
|         struct Fun_Helper<true> | ||||
|         { | ||||
|           template<typename T, typename Class> | ||||
|             static Proxy_Function go(T Class::* m) | ||||
|             { | ||||
|               return Proxy_Function(new Attribute_Access<T, Class>(m)); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -106,9 +87,31 @@ namespace chaiscript | ||||
|   ///  | ||||
|   /// \sa \ref adding_functions | ||||
|   template<typename T> | ||||
|     Proxy_Function fun(T t) | ||||
|     Proxy_Function fun(const T &t) | ||||
|     { | ||||
|       return dispatch::detail::Fun_Helper<std::is_member_object_pointer<T>::value>::go(t); | ||||
|       return Proxy_Function( | ||||
|           static_cast<dispatch::Proxy_Function_Impl_Base *>(new dispatch::Proxy_Function_Impl<typename dispatch::detail::FunctionSignature<decltype(dispatch::detail::to_function(t)) >::Signature>(dispatch::detail::to_function(t)))); | ||||
|     } | ||||
|  | ||||
|   template<typename Ret, typename Class, typename ... Param> | ||||
|     Proxy_Function fun(Ret (Class::*func)(Param...) const) | ||||
|     { | ||||
|       return Proxy_Function( | ||||
|           static_cast<dispatch::Proxy_Function_Impl_Base *>(new dispatch::Proxy_Function_Impl<typename dispatch::detail::FunctionSignature<decltype(dispatch::detail::to_function(func)) >::Signature>(dispatch::detail::to_function(func)))); | ||||
|     } | ||||
|  | ||||
|   template<typename Ret, typename Class, typename ... Param> | ||||
|     Proxy_Function fun(Ret (Class::*func)(Param...)) | ||||
|     { | ||||
|       return Proxy_Function( | ||||
|           static_cast<dispatch::Proxy_Function_Impl_Base *>(new dispatch::Proxy_Function_Impl<typename dispatch::detail::FunctionSignature<decltype(dispatch::detail::to_function(func)) >::Signature>(dispatch::detail::to_function(func)))); | ||||
|     } | ||||
|  | ||||
|  | ||||
|   template<typename T, typename Class /*, typename = typename std::enable_if<std::is_member_object_pointer<T>::value>::type*/> | ||||
|     Proxy_Function fun(T Class::* m /*, typename std::enable_if<std::is_member_object_pointer<T>::value>::type* = 0*/ ) | ||||
|     { | ||||
|       return Proxy_Function(new dispatch::Attribute_Access<T, Class>(m)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -149,9 +152,9 @@ namespace chaiscript | ||||
|   ///  | ||||
|   /// \sa \ref adding_functions | ||||
|   template<typename T, typename Q> | ||||
|     Proxy_Function fun(T t, const Q &q) | ||||
|     Proxy_Function fun(T &&t, const Q &q) | ||||
|     { | ||||
|       return fun(detail::bind_first(t, q)); | ||||
|       return fun(detail::bind_first(std::forward<T>(t), q)); | ||||
|     } | ||||
|  | ||||
|   /// \brief Creates a new Proxy_Function object from a free function or member function and binds the first and second parameters of it | ||||
| @@ -175,9 +178,9 @@ namespace chaiscript | ||||
|   ///  | ||||
|   /// \sa \ref adding_functions | ||||
|   template<typename T, typename Q, typename R> | ||||
|     Proxy_Function fun(T t, const Q &q, const R &r) | ||||
|     Proxy_Function fun(T &&t, Q &&q, R &&r) | ||||
|     { | ||||
|       return fun(detail::bind_first(detail::bind_first(t, q), r)); | ||||
|       return fun(detail::bind_first(detail::bind_first(std::forward<T>(t), std::forward<Q>(q)), std::forward<R>(r))); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -367,7 +367,13 @@ namespace chaiscript | ||||
|               [this](const std::vector<Boxed_Value> &t_params) { | ||||
|                 return m_engine.call_exists(t_params); | ||||
|               })), "call_exists"); | ||||
|       m_engine.add(fun<Boxed_Value (const dispatch::Proxy_Function_Base *, const std::vector<Boxed_Value> &)>(std::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), std::placeholders::_1, std::placeholders::_2, std::ref(m_engine.conversions()))), "call"); | ||||
|  | ||||
| //      m_engine.add(fun<Boxed_Value (const dispatch::Proxy_Function_Base *, const std::vector<Boxed_Value> &)>(std::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), std::placeholders::_1, std::placeholders::_2, std::ref(m_engine.conversions()))), "call"); | ||||
| // | ||||
|       m_engine.add(fun<Boxed_Value (const dispatch::Proxy_Function_Base &, const std::vector<Boxed_Value> &)>( | ||||
|             [=](const dispatch::Proxy_Function_Base &t_fun, const std::vector<Boxed_Value> &t_params) { | ||||
|               return t_fun(t_params, this->m_engine.conversions()); | ||||
|             }), "call"); | ||||
|  | ||||
|       m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name"); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jason Turner
					Jason Turner