| 588 | }; |
| 589 | |
| 590 | class cni final { |
| 591 | template <typename T> |
| 592 | struct construct_helper |
| 593 | { |
| 594 | template <typename X, typename RetT, typename... ArgsT> |
| 595 | static cni_holder_base *_construct(X &&val, RetT (*target_function)(ArgsT...)) |
| 596 | { |
| 597 | using source_function_type = typename cni_decayed_conversion_cpp<RetT>::target_type (*)( |
| 598 | typename cni_decayed_conversion_cs<ArgsT>::source_type...); |
| 599 | // Return type |
| 600 | static_assert(cni_convertible<RetT, typename cni_decayed_conversion_cpp<RetT>::target_type>::value, |
| 601 | "Invalid conversion."); |
| 602 | // Argument type |
| 603 | check_conversion(target_function, source_function_type(nullptr)); |
| 604 | return new cni_holder<T, source_function_type>(std::forward<X>(val)); |
| 605 | } |
| 606 | |
| 607 | template <typename X> |
| 608 | static cni_holder_base *construct(X &&val) |
| 609 | { |
| 610 | return _construct(std::forward<X>(val), typename cov::function_parser<T>::type::common_type(nullptr)); |
| 611 | } |
| 612 | }; |
| 613 | |
| 614 | cni_holder_base *mCni = nullptr; |
| 615 | |
| 616 | public: |
| 617 | cni() = delete; |
| 618 | |
| 619 | cni(const cni &c) : mCni(c.mCni->clone()) {} |
| 620 | |
| 621 | template <typename T> |
| 622 | explicit cni(T &&val) : mCni( |
| 623 | construct_helper<typename cni_modify<typename std::remove_reference<T>::type>::type>::construct( |
| 624 | std::forward<T>(val))) |
| 625 | { |
| 626 | } |
| 627 | |
| 628 | template <typename T, typename X> |
| 629 | cni(T &&val, cni_type<X>) : mCni( |
| 630 | new cni_holder<typename cni_modify<typename std::remove_reference<T>::type>::type, typename cni_modify<X>::type>( |
| 631 | std::forward<T>(val))) |
| 632 | { |
| 633 | // Analysis the function |
| 634 | using target_function_type = typename cov::function_parser<typename cni_modify<typename std::remove_reference<T>::type>::type>::type::common_type; |
| 635 | using source_function_type = typename cov::function_parser<typename cni_modify<X>::type>::type::common_type; |
| 636 | // Check consistency |
| 637 | // Argument size |
| 638 | static_assert( |
| 639 | count_args_size(target_function_type(nullptr)) == count_args_size(source_function_type(nullptr)), |
| 640 | "Invalid argument size."); |
| 641 | // Return type |
| 642 | static_assert( |
| 643 | cni_convertible<typename cov::function_parser<target_function_type>::type::return_type, typename cov::function_parser<source_function_type>::type::return_type>::value, |
| 644 | "Invalid conversion."); |
| 645 | // Argument type |
| 646 | check_conversion(target_function_type(nullptr), source_function_type(nullptr)); |
| 647 | } |
no outgoing calls
no test coverage detected