@@ -102,18 +102,29 @@ struct Identity
102102// /////////////////////////////////////////////////////////////////////////////////////////////////
103103struct DontMove {};
104104
105+ // /////////////////////////////////////////////////////////////////////////////////////////////////
106+ // / DisableIfSame
107+ // /////////////////////////////////////////////////////////////////////////////////////////////////
108+ template <typename T, typename U>
109+ struct DisableIfSame :
110+ std::enable_if<! std::is_same<
111+ typename std::decay<T>::type,
112+ typename std::decay<U>::type>::value> {};
113+
105114// /////////////////////////////////////////////////////////////////////////////////////////////////
106115// / AddDummyArgWrapper
107116// /////////////////////////////////////////////////////////////////////////////////////////////////
108117template <typename TArg, typename F, typename TRet, typename ... TDepValues>
109118struct AddDummyArgWrapper
110119{
111- // Dummy int to make sure it calls the right ctor
112- template <typename FIn>
113- AddDummyArgWrapper (int , FIn&& func) : MyFunc( std::forward<FIn>(func) ) {}
114-
115120 AddDummyArgWrapper (const AddDummyArgWrapper& other) = default ;
116- AddDummyArgWrapper (AddDummyArgWrapper&& other) : MyFunc( std::move(other.MyFunc) ) {}
121+
122+ AddDummyArgWrapper (AddDummyArgWrapper&& other) :
123+ MyFunc ( std::move(other.MyFunc) )
124+ {}
125+
126+ template <typename FIn, class = typename DisableIfSame<FIn,AddDummyArgWrapper>::type>
127+ explicit AddDummyArgWrapper (FIn&& func) : MyFunc( std::forward<FIn>(func) ) {}
117128
118129 TRet operator ()(TArg, TDepValues& ... args)
119130 {
@@ -126,12 +137,15 @@ struct AddDummyArgWrapper
126137template <typename TArg, typename F, typename ... TDepValues>
127138struct AddDummyArgWrapper <TArg,F,void ,TDepValues...>
128139{
129- // Dummy int to make sure it calls the right ctor
130- template <typename FIn>
131- AddDummyArgWrapper (int , FIn&& func) : MyFunc( std::forward<FIn>(func) ) {}
132-
140+ public:
133141 AddDummyArgWrapper (const AddDummyArgWrapper& other) = default ;
134- AddDummyArgWrapper (AddDummyArgWrapper&& other) : MyFunc( std::move(other.MyFunc) ) {}
142+
143+ AddDummyArgWrapper (AddDummyArgWrapper&& other) :
144+ MyFunc ( std::move(other.MyFunc) )
145+ {}
146+
147+ template <typename FIn, class = typename DisableIfSame<FIn,AddDummyArgWrapper>::type>
148+ explicit AddDummyArgWrapper (FIn&& func) : MyFunc( std::forward<FIn>(func) ) {}
135149
136150 void operator ()(TArg, TDepValues& ... args)
137151 {
@@ -152,8 +166,20 @@ template
152166>
153167struct AddDefaultReturnValueWrapper
154168{
155- template <typename FIn>
156- AddDefaultReturnValueWrapper (FIn&& func) : MyFunc( std::forward<FIn>(func) ) {}
169+ AddDefaultReturnValueWrapper (const AddDefaultReturnValueWrapper&) = default ;
170+
171+ AddDefaultReturnValueWrapper (AddDefaultReturnValueWrapper&& other) :
172+ MyFunc ( std::move(other.MyFunc) )
173+ {}
174+
175+ template
176+ <
177+ typename FIn,
178+ class = typename DisableIfSame<FIn,AddDefaultReturnValueWrapper>::type
179+ >
180+ explicit AddDefaultReturnValueWrapper (FIn&& func) :
181+ MyFunc( std::forward<FIn>(func) )
182+ {}
157183
158184 template <typename ... TArgs>
159185 TRet operator ()(TArgs&& ... args)
@@ -165,6 +191,33 @@ struct AddDefaultReturnValueWrapper
165191 F MyFunc;
166192};
167193
194+ // /////////////////////////////////////////////////////////////////////////////////////////////////
195+ // / IsCallableWith
196+ // /////////////////////////////////////////////////////////////////////////////////////////////////
197+ template
198+ <
199+ typename F,
200+ typename TRet,
201+ typename ... TArgs
202+ >
203+ class IsCallableWith
204+ {
205+ private:
206+ using NoT = char [1 ];
207+ using YesT = char [2 ];
208+
209+ template <typename U>
210+ static YesT& check (
211+ decltype ( static_cast <TRet>(
212+ (std::declval<U>())(std::declval<TArgs>() ...))) *);
213+
214+ template <typename U>
215+ static NoT& check (...);
216+
217+ public:
218+ enum { value = sizeof (check<F>(nullptr )) == sizeof (YesT) };
219+ };
220+
168221/* ***************************************/ REACT_IMPL_END /* **************************************/
169222
170223// Expand args by wrapping them in a dummy function
0 commit comments