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);