19 #ifndef LIB_CS_INTERNAL_H
20 #define LIB_CS_INTERNAL_H
26 #if ! defined (CS_DOXYPRESS)
35 template<
class T,
class U,
class =
void>
36 class cs_check_connect_args
37 :
public cs_check_connect_args<T,
decltype(&U::operator())>
43 template<
class T,
class ...ArgsX,
class ...ArgsY>
44 class cs_check_connect_args<
void (*)(T, ArgsX...),
void (*)(T, ArgsY...)>
45 :
public cs_check_connect_args<
void (*) (ArgsX...),
void (*) (ArgsY...)>
50 template<
class ...ArgsX>
51 class cs_check_connect_args<
void (*)(ArgsX...),
void (*)()>
52 :
public std::integral_constant<
bool,
true>
57 template<
class ...ArgsX,
class ...ArgsY>
58 class cs_check_connect_args <
void (*)(ArgsX...),
void (*)(ArgsY...),
59 typename std::enable_if<
sizeof...(ArgsX) ==
sizeof...(ArgsY) &&
60 ! std::is_same<std::tuple<ArgsX...>, std::tuple<ArgsY...>>::value >::type>
61 :
public std::integral_constant<
bool,
false>
66 template<
class ...ArgsX,
class ...ArgsY>
67 class cs_check_connect_args <
void (*)(ArgsX...),
void (*)(ArgsY...),
68 typename std::enable_if<
sizeof...(ArgsX) <
sizeof...(ArgsY)>::type >
69 :
public std::integral_constant<
bool,
false>
75 template<
class T,
class...ArgsX,
class...ArgsY>
76 class cs_check_connect_args<
void (*)(ArgsX...),
void (T::*)(ArgsY...) >
77 :
public cs_check_connect_args<
void (*)(ArgsX...),
void (*) (ArgsY...)>
82 template<
class T,
class...ArgsX,
class...ArgsY>
83 class cs_check_connect_args<
void (*)(ArgsX...),
void (T::*)(ArgsY...)
const>
84 :
public cs_check_connect_args<
void (*)(ArgsX...),
void (*) (ArgsY...)>
90 template<
class Sender,
class SignalClass>
91 void cs_testConnect_SenderSignal()
93 static_assert( std::is_base_of<SignalClass, Sender>::value,
94 "Signal is not defined in the sender class");
97 template<
class Slot_LambdaType,
class ...SignalArgs>
98 void cs_testConnect_SignalSlotArgs_1()
100 static_assert( cs_check_connect_args<
void (*)(SignalArgs...), Slot_LambdaType>::value,
101 "Incompatible signal/slot arguments");
104 template<
class SlotClass,
class Receiver>
105 void cs_testConnect_ReceiverSlot()
107 static_assert( std::is_base_of<SlotClass, Receiver>::value,
108 "Slot is not defined in the receiver class");
111 template<
class Signal_ArgType,
class Slot_ArgType>
112 void cs_testConnect_SignalSlotArgs_2()
114 static_assert( cs_check_connect_args<Signal_ArgType, Slot_ArgType>::value,
115 "Incompatible signal/slot arguments");
127 template<
typename ...FunctionArgTypes,
typename FunctionReturn,
typename ...TupleTypes, size_t ...Ks>
128 FunctionReturn cs_unpack_function_args_internal(FunctionReturn (*functionPtr)(FunctionArgTypes...),
129 const std::tuple<TupleTypes...> &data, std::index_sequence<Ks...>)
131 return functionPtr(std::get<Ks>(data)...);
135 template<
typename ...FunctionArgTypes,
typename FunctionReturn,
typename ...TupleTypes>
136 FunctionReturn cs_unpack_function_args(FunctionReturn (*functionPtr)(FunctionArgTypes...),
137 const std::tuple<TupleTypes...> &data)
139 return cs_unpack_function_args_internal(functionPtr, data, std::index_sequence_for<TupleTypes...> {} );
143 template<
typename ...FunctionArgTypes,
typename ...TupleTypes>
144 CSVoidReturn cs_unpack_function_args(
void (*functionPtr)(FunctionArgTypes...),
const std::tuple<TupleTypes...> &data)
146 cs_unpack_function_args_internal(functionPtr, data, std::index_sequence_for<TupleTypes...> {} );
147 return CSVoidReturn {};
154 template<
typename MethodClass,
class MethodReturn,
typename ...MethodArgTypes,
typename ...TupleTypes, size_t ...Ks>
155 MethodReturn cs_unpack_method_args_internal(MethodClass *obj, MethodReturn (MethodClass::*methodPtr)(MethodArgTypes...),
156 const std::tuple<TupleTypes...> &data, std::index_sequence<Ks...>)
158 return (obj->*methodPtr)(std::get<Ks>(data)...);
162 template<
typename MethodClass,
class MethodReturn,
typename ...MethodArgTypes,
typename ...TupleTypes>
163 MethodReturn cs_unpack_method_args(MethodClass *obj, MethodReturn (MethodClass::*methodPtr)(MethodArgTypes...),
164 const std::tuple<TupleTypes...> &data)
166 return cs_unpack_method_args_internal(obj, methodPtr, data, std::index_sequence_for<TupleTypes...> {} );
170 template<
typename MethodClass,
typename ...MethodArgTypes,
typename ...TupleTypes>
171 CSVoidReturn cs_unpack_method_args(MethodClass *obj,
void (MethodClass::*methodPtr)(MethodArgTypes...),
172 const std::tuple<TupleTypes...> &data)
174 cs_unpack_method_args_internal(obj, methodPtr, data, std::index_sequence_for<TupleTypes...> {} );
175 return CSVoidReturn {};
180 template<
typename MethodClass,
class MethodReturn,
typename ...MethodArgTypes,
typename ...TupleTypes, size_t ...Ks>
181 MethodReturn cs_unpack_method_args_internal(
const MethodClass *obj,
182 MethodReturn (MethodClass::*methodPtr)(MethodArgTypes...)
const,
183 const std::tuple<TupleTypes...> &data, std::index_sequence<Ks...>)
185 return (obj->*methodPtr)(std::get<Ks>(data)...);
189 template<
typename MethodClass,
class MethodReturn,
typename ...MethodArgTypes,
typename ...TupleTypes>
190 MethodReturn cs_unpack_method_args(
const MethodClass *obj,
191 MethodReturn (MethodClass::*methodPtr)(MethodArgTypes...)
const,
192 const std::tuple<TupleTypes...> &data)
194 return cs_unpack_method_args_internal(obj, methodPtr, data, std::index_sequence_for<TupleTypes...> {} );
198 template<
typename MethodClass,
typename ...MethodArgTypes,
typename ...TupleTypes>
199 CSVoidReturn cs_unpack_method_args(
const MethodClass *obj,
void (MethodClass::*methodPtr)(MethodArgTypes...)
const,
200 const std::tuple<TupleTypes...> &data)
202 cs_unpack_method_args_internal(obj, methodPtr, data, std::index_sequence_for<TupleTypes...> {} );
203 return CSVoidReturn {};
209 template <
class T1,
class T2>
215 template <
class T,
class ...Ts>
216 class prePend<T, std::tuple<Ts...>>
219 using type =
typename std::tuple<T, Ts...>;
227 using type =
typename std::tuple<>;
230 template <
class T1,
class T2,
class ...Ts>
231 class strip<std::tuple<T1, T2, Ts...>>
234 using type =
typename prePend<T1,
typename strip<std::tuple<T2, Ts...> >::type>::type;
240 template<
unsigned int ...Vs>
245 template<
unsigned int Max,
unsigned int ...Vs>
246 class makeIntValues :
public makeIntValues <Max - 1, Max - 1, Vs...>
250 template<
unsigned int ...Vs>
251 class makeIntValues<0, Vs...> :
public intValues<Vs...>
257 template <
class ...Ts>
261 using type =
typename strip< std::tuple<Ts...> >::type;
268 template<
unsigned int ...Vs,
class ...Ts>
269 typename removeLastType<Ts...>::type internalRemoveData(intValues<Vs...>, std::tuple<Ts...> tupleValue)
272 return std::forward_as_tuple(std::get<Vs>(tupleValue)...);
275 template<
class ...Ts>
276 typename removeLastType<Ts...>::type funcRemoveData(std::tuple<Ts...> tupleValue)
278 return internalRemoveData(makeIntValues<
sizeof...(Ts) - 1>(), tupleValue);
287 virtual ~TeaCupAbstract() {}
291 template<
class ...Ts>
292 class TeaCup :
public TeaCup<
typename removeLastType<Ts...>::type>
296 explicit TeaCup(T lambda);
298 std::tuple<Ts...> getData()
const;
301 std::function<std::tuple<Ts...> ()> m_lambda;
304 template<
class ...Ts>
306 TeaCup<Ts...>::TeaCup(T lambda)
307 : TeaCup<
typename removeLastType<Ts...>::type >( [
this]() {
return funcRemoveData(m_lambda()); } ),
308 m_lambda(std::move(lambda))
312 template<
class ...Ts>
313 std::tuple<Ts...> TeaCup<Ts...>::getData()
const
320 class TeaCup<>:
public TeaCupAbstract
324 explicit TeaCup(T lambda);
326 std::tuple<> getData()
const;
334 inline std::tuple<> TeaCup<>::getData()
const
337 return std::tuple<> {};
341 template<
class ...Ts>
342 class TeaCup< std::tuple<Ts...> >:
public TeaCup<Ts...>
346 explicit TeaCup(T lambda);
349 template<
class ...Ts>
351 TeaCup<std::tuple<Ts...>>::TeaCup(T lambda)
352 : TeaCup<Ts...>(std::move(lambda))
359 template<
class R,
class T, size_t ...Ks>
360 R convert_tuple_internal(T &data, std::index_sequence<Ks...>)
362 return R {std::get<Ks>(data)...};
365 template<
class R,
class ...Ts>
366 R convert_tuple(std::tuple<Ts...> &data)
368 return convert_tuple_internal<R> (data, std::index_sequence_for<Ts...> {} );
374 template<
class ...Ts>
375 class TeaCup_Data:
public TeaCup<Ts...>
378 TeaCup_Data(
bool needs_copying, Ts...);
379 std::tuple<Ts...> getData()
const;
382 std::shared_ptr< std::tuple<
typename std::remove_reference<Ts>::type...> > m_copyOfData;
383 std::tuple<Ts...> m_data;
386 template<
class ...Ts>
387 TeaCup_Data<Ts...>::TeaCup_Data(
bool needs_copying, Ts...Vs)
388 : TeaCup<Ts...>( [
this]() {
return m_data; } ),
389 m_copyOfData(needs_copying ?
new std::tuple<
typename std::remove_reference<Ts>::type...> (Vs...) :
nullptr),
390 m_data(needs_copying ? convert_tuple<std::tuple<Ts...>> (*m_copyOfData) : std::tuple<Ts...> (Vs...) )
394 template<
class ...Ts>
395 std::tuple<Ts...> TeaCup_Data<Ts...>::getData()
const
406 virtual ~BentoAbstract() {}
408 virtual bool operator ==(
const BentoAbstract &right)
const = 0;
409 bool operator !=(
const BentoAbstract &right)
const;
411 virtual void invoke(SlotBase *receiver,
const TeaCupAbstract *dataPack)
const = 0;
412 virtual std::unique_ptr<BentoAbstract> clone()
const = 0;
415 inline bool BentoAbstract::operator !=(
const BentoAbstract &right)
const
417 return ! (*
this == right);
421 class Bento :
public virtual BentoAbstract
426 bool operator ==(
const BentoAbstract &right)
const override;
428 void invoke(SlotBase *receiver,
const TeaCupAbstract *dataPack)
const override;
429 std::unique_ptr<BentoAbstract> clone()
const override;
431 template<
class MethodReturn,
class ...MethodArgs>
432 void invoke_internal(
const TeaCupAbstract *dataPack, MethodReturn (T::*methodPtr)(MethodArgs...)
const)
const;
434 template<
class MethodReturn,
class ...MethodArgs>
435 void invoke_internal(
const TeaCupAbstract *dataPack, MethodReturn (T::*methodPtr)(MethodArgs...))
const;
440 template<
class FunctionReturn,
class ...FunctionArgs>
441 class Bento<FunctionReturn (*)(FunctionArgs...)> :
public virtual BentoAbstract
444 Bento(FunctionReturn (*ptr)(FunctionArgs...));
446 bool operator ==(
const BentoAbstract &right)
const override;
448 std::unique_ptr<BentoAbstract> clone()
const override;
449 void invoke(SlotBase *receiver,
const TeaCupAbstract *dataPack)
const override;
451 FunctionReturn (*m_methodPtr)(FunctionArgs...);
454 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
455 class Bento<MethodReturn(MethodClass::*)(MethodArgs...)>:
public virtual BentoAbstract
458 Bento(MethodReturn(MethodClass::*ptr)(MethodArgs...) );
460 bool operator ==(
const BentoAbstract &right)
const override ;
461 void invoke(SlotBase *receiver,
const TeaCupAbstract *dataPack)
const override;
462 std::unique_ptr<BentoAbstract> clone()
const override;
464 MethodReturn(MethodClass::*m_methodPtr)(MethodArgs...);
468 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
469 class Bento<MethodReturn(MethodClass::*)(MethodArgs...)
const>:
public virtual BentoAbstract
472 Bento(MethodReturn(MethodClass::*ptr)(MethodArgs...)
const);
474 bool operator ==(
const BentoAbstract &right)
const override;
476 void invoke(SlotBase *receiver,
const TeaCupAbstract *dataPack)
const override;
477 std::unique_ptr<BentoAbstract> clone()
const override;
479 MethodReturn(MethodClass::*m_methodPtr)(MethodArgs...)
const;
485 Bento<T>::Bento(T lambda)
491 std::unique_ptr<BentoAbstract> Bento<T>::clone()
const
493 return std::make_unique<Bento<T>>(*
this);
497 bool Bento<T>::operator ==(
const BentoAbstract &)
const
504 void Bento<T>::invoke(SlotBase *,
const TeaCupAbstract *dataPack)
const
507 auto methodPtr = &T::operator();
509 this->invoke_internal(dataPack, methodPtr);
513 template<
class MethodReturn,
class ...MethodArgs>
514 void Bento<T>::invoke_internal(
const TeaCupAbstract *dataPack, MethodReturn (T::*methodPtr)(MethodArgs...)
const)
const
520 const TeaCup<MethodArgs...> *teaCup =
dynamic_cast<
const TeaCup<MethodArgs...> *>(dataPack);
524 std::tuple<MethodArgs...> &&args = teaCup->getData();
527 cs_unpack_method_args(&m_lambda, methodPtr, args);
532 template<
class MethodReturn,
class ...MethodArgs>
533 void Bento<T>::invoke_internal(
const TeaCupAbstract *dataPack, MethodReturn (T::*methodPtr)(MethodArgs...))
const
539 const TeaCup<MethodArgs...> *teaCup =
dynamic_cast<
const TeaCup<MethodArgs...> *>(dataPack);
543 std::tuple<MethodArgs...> &&args = teaCup->getData();
545 auto object =
const_cast<
typename std::remove_const<T>::type *>(&m_lambda);
548 cs_unpack_method_args(object, methodPtr, args);
553 template<
class FunctionReturn,
class ...FunctionArgs>
554 Bento<FunctionReturn (*)(FunctionArgs...)>::Bento(FunctionReturn (*ptr)(FunctionArgs...)) :
559 template<
class FunctionReturn,
class ...FunctionArgs>
560 std::unique_ptr<BentoAbstract> Bento<FunctionReturn (*)(FunctionArgs...)>::clone()
const
562 return std::make_unique<Bento<FunctionReturn (*)(FunctionArgs...)>>(*
this);
565 template<
class FunctionReturn,
class ...FunctionArgs>
566 bool Bento<FunctionReturn (*)(FunctionArgs...)>::operator ==(
const BentoAbstract &right)
const
570 const Bento<FunctionReturn (*)(FunctionArgs...)> *temp;
571 temp =
dynamic_cast<
const Bento <FunctionReturn (*)(FunctionArgs...)> *> (&right);
574 retval = (
this->m_methodPtr == temp->m_methodPtr);
580 template<
class FunctionReturn,
class ...FunctionArgs>
581 void Bento<FunctionReturn (*)(FunctionArgs...)>::invoke(SlotBase *,
const TeaCupAbstract *dataPack)
const
587 const TeaCup<FunctionArgs...> *teaCup =
dynamic_cast<
const TeaCup<FunctionArgs...> *>(dataPack);
591 std::tuple<FunctionArgs...> &&args = teaCup->getData();
594 cs_unpack_function_args(m_methodPtr, args);
600 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
601 Bento<MethodReturn(MethodClass::*)(MethodArgs...)>::Bento(MethodReturn(MethodClass::*ptr)(MethodArgs...))
606 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
607 std::unique_ptr<BentoAbstract> Bento<MethodReturn(MethodClass::*)(MethodArgs...)>::clone()
const
609 return std::make_unique<Bento<MethodReturn(MethodClass::*)(MethodArgs...)>>(*
this);
612 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
613 bool Bento<MethodReturn(MethodClass::*)(MethodArgs...)>::operator ==(
const BentoAbstract &right)
const
617 const Bento<MethodReturn(MethodClass::*)(MethodArgs...)> *temp;
618 temp =
dynamic_cast<
const Bento <MethodReturn(MethodClass::*)(MethodArgs...)> *> (&right);
621 retval = (
this->m_methodPtr == temp->m_methodPtr);
627 template<
class MethodClass,
class MethodReturn,
class ...MethodArgs>
628 void Bento<MethodReturn(MethodClass::*)(MethodArgs...)>::invoke(SlotBase *receiver,
const TeaCupAbstract *dataPack)
const
634 MethodClass *t_receiver =
dynamic_cast<MethodClass *>(receiver);
639 const TeaCup<MethodArgs...> *teaCup =
dynamic_cast<
const TeaCup<MethodArgs...> *>(dataPack);
643 std::tuple<MethodArgs...> &&args = teaCup->getData();
646 cs_unpack_method_args(t_receiver, m_methodPtr, args);
653 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
654 Bento<MethodReturn(MethodClass::*)(MethodArgs...)
const>::Bento(MethodReturn(MethodClass::*ptr)(MethodArgs...)
const)
659 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
660 std::unique_ptr<BentoAbstract> Bento<MethodReturn(MethodClass::*)(MethodArgs...)
const>::clone()
const
662 return std::make_unique<Bento<MethodReturn(MethodClass::*)(MethodArgs...)
const>>(*
this);
665 template<
class MethodClass,
class MethodReturn,
class...MethodArgs>
666 bool Bento<MethodReturn(MethodClass::*)(MethodArgs...)
const>::operator ==(
const BentoAbstract &right)
const
670 const Bento<MethodReturn(MethodClass::*)(MethodArgs...)
const> *temp;
671 temp =
dynamic_cast<
const Bento <MethodReturn(MethodClass::*)(MethodArgs...)
const> *> (&right);
674 retval = (
this->m_methodPtr == temp->m_methodPtr);
680 template<
class MethodClass,
class MethodReturn,
class ...MethodArgs>
681 void Bento<MethodReturn(MethodClass::*)(MethodArgs...)
const>::invoke(SlotBase *receiver,
const TeaCupAbstract *dataPack)
const
687 MethodClass *t_receiver =
dynamic_cast<MethodClass *>(receiver);
693 const TeaCup<MethodArgs...> *teaCup =
dynamic_cast<
const TeaCup<MethodArgs...> *>(dataPack);
697 std::tuple<MethodArgs...> &&args = teaCup->getData();
700 cs_unpack_method_args(t_receiver, m_methodPtr, args);