Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions src/vu8/Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
#include <vu8/detail/Proto.hpp>
#include <vu8/detail/Singleton.hpp>
#include <vu8/detail/Class.hpp>
#include <vu8/detail/TypeTraits.hpp>

#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/include/push_front.hpp>
#include <boost/fusion/include/join.hpp>

#include <boost/type_traits/is_void.hpp>

#include <iostream>
#include <stdexcept>

Expand Down Expand Up @@ -64,7 +67,7 @@ struct ClassSingletonFactory<M, NoFactory> {

template <class T, class Factory>
class ClassSingleton
: detail::LazySingleton< ClassSingleton<T, Factory> >,
: private detail::LazySingleton< ClassSingleton<T, Factory> >,
public ClassSingletonFactory<ClassSingleton<T, Factory>, Factory>
{
friend class ClassSingletonFactory<ClassSingleton<T, Factory>, Factory>;
Expand Down Expand Up @@ -96,20 +99,38 @@ class ClassSingleton
}

template <class P>
static inline typename boost::disable_if<
boost::is_same<void, typename P::return_type>, ValueHandle >::type
ForwardReturn(T *obj, const v8::Arguments& args) {
static inline typename
boost::enable_if<vu8::is_to_v8_convertible<typename P::return_type>,
ValueHandle >::type ForwardReturn (T *obj, const v8::Arguments& args) {
return ToV8(Invoke<P>(obj, args));
}

template <class P>
static inline typename boost::enable_if<
boost::is_same<void, typename P::return_type>, ValueHandle >::type
ForwardReturn(T *obj, const v8::Arguments& args) {
static inline typename
boost::enable_if<boost::is_void<typename P::return_type>,
ValueHandle >::type ForwardReturn (T *obj, const v8::Arguments& args) {
Invoke<P>(obj, args);
return v8::Undefined();
}

template <class P>
static inline typename
boost::enable_if<typename P::IS_RETURN_WRAPPED_CLASS,
ValueHandle >::type ForwardReturn (T *obj, const v8::Arguments& args) {
typedef typename P::ClassSingleton LocalSelf;
typedef typename P::return_type ReturnType;

v8::HandleScope scope;
ReturnType* return_value = new ReturnType(Invoke<P>(obj, args));
v8::Local<v8::Object> localObj =
LocalSelf::Instance().func_->GetFunction()->NewInstance();
v8::Persistent<v8::Object> persistentObj =
v8::Persistent<v8::Object>::New(localObj);
persistentObj->SetInternalField(0, v8::External::New(return_value));
persistentObj.MakeWeak(return_value, &LocalSelf::MadeWeak);
return scope.Close(localObj);
}

// every method is run inside a handle scope
template <class P>
static inline ValueHandle Forward(const v8::Arguments& args) {
Expand Down
26 changes: 25 additions & 1 deletion src/vu8/detail/ProtoHelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@
# include <boost/preprocessor/punctuation/comma_if.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/type_traits/integral_constant.hpp>

# ifndef VU8_PROTO_MAX_SIZE
# define VU8_PROTO_MAX_SIZE VU8_PP_ITERATION_LIMIT
# endif
namespace vu8 { namespace detail {
namespace vu8 {

template <class T, class F> struct Class;
template <class T, class F> struct ClassSingleton;

namespace detail {

namespace mpl = boost::mpl;

Expand Down Expand Up @@ -48,12 +54,30 @@ template <class C, class R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)
struct MemFunProto<C, R ( BOOST_PP_ENUM_PARAMS(n, A) )> : FunProtoBase<R> {
typedef mpl::vector<BOOST_PP_ENUM_PARAMS(n, A)> arguments;
typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A));
typedef boost::false_type IS_RETURN_WRAPPED_CLASS;
};

template <class C, class R, class Factory BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)>
struct MemFunProto<C, vu8::Class<R, Factory> ( BOOST_PP_ENUM_PARAMS(n, A) )> : FunProtoBase<R> {
typedef mpl::vector<BOOST_PP_ENUM_PARAMS(n, A)> arguments;
typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A));
typedef boost::true_type IS_RETURN_WRAPPED_CLASS;
typedef vu8::ClassSingleton<R, Factory> ClassSingleton;
};

template <class C, class R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)>
struct MemFunProto<C const, R ( BOOST_PP_ENUM_PARAMS(n, A) )> : FunProtoBase<R> {
typedef mpl::vector<BOOST_PP_ENUM_PARAMS(n, A)> arguments;
typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A)) const;
typedef boost::false_type IS_RETURN_WRAPPED_CLASS;
};

template <class C, class R, class Factory BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)>
struct MemFunProto<C const, vu8::Class<R, Factory> ( BOOST_PP_ENUM_PARAMS(n, A) )> : FunProtoBase<R> {
typedef mpl::vector<BOOST_PP_ENUM_PARAMS(n, A)> arguments;
typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A)) const;
typedef boost::true_type IS_RETURN_WRAPPED_CLASS;
typedef vu8::ClassSingleton<R, Factory> ClassSingleton;
};

} }
Expand Down
43 changes: 43 additions & 0 deletions src/vu8/detail/TypeTraits.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef TYPETRAITS_HPP_
#define TYPETRAITS_HPP_

#include <string>

#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>

#include <boost/utility/enable_if.hpp>

#include <v8.h>

namespace vu8 {

template <class T> struct remove_reference_and_const {
typedef typename boost::remove_const<
typename boost::remove_reference<T>::type
>::type type;
};

template <class T, class Enable = void>
struct is_to_v8_convertible : public boost::false_type { };

template <class T>
struct is_to_v8_convertible<T, typename boost::enable_if<
boost::is_arithmetic<T>
>::type> : public boost::true_type { };

#define VU8_TO_V8_CONV_TYPE_TRAIT_SPEC(T,M,spec) \
template <class T > \
struct is_to_v8_convertible<T, typename boost::enable_if< \
boost::is_same<M, spec > \
>::type> : public boost::true_type { }; \
/**/

VU8_TO_V8_CONV_TYPE_TRAIT_SPEC(T,T,v8::Handle<v8::Value>);
VU8_TO_V8_CONV_TYPE_TRAIT_SPEC(T,typename remove_reference_and_const<T>::type, std::string);
}

#endif /* TYPETRAITS_HPP_ */