|
10 | 10 | // Note: Do not include this file directly! Include "napi.h" instead.
|
11 | 11 |
|
12 | 12 | #include <cstring>
|
| 13 | +#include <type_traits> |
13 | 14 |
|
14 | 15 | namespace Napi {
|
15 | 16 |
|
@@ -599,6 +600,106 @@ inline Symbol::Symbol() : Name() {
|
599 | 600 | inline Symbol::Symbol(napi_env env, napi_value value) : Name(env, value) {
|
600 | 601 | }
|
601 | 602 |
|
| 603 | +//////////////////////////////////////////////////////////////////////////////// |
| 604 | +// Automagic value creation |
| 605 | +//////////////////////////////////////////////////////////////////////////////// |
| 606 | + |
| 607 | +namespace details { |
| 608 | +template <typename T> |
| 609 | +struct vf_number { |
| 610 | + static Number From(napi_env env, T value) { |
| 611 | + return Number::New(env, static_cast<double>(value)); |
| 612 | + } |
| 613 | +}; |
| 614 | + |
| 615 | +template<> |
| 616 | +struct vf_number<bool> { |
| 617 | + static Boolean From(napi_env env, bool value) { |
| 618 | + return Boolean::New(env, value); |
| 619 | + } |
| 620 | +}; |
| 621 | + |
| 622 | +struct vf_utf8_charp { |
| 623 | + static String From(napi_env env, const char* value) { |
| 624 | + return String::New(env, value); |
| 625 | + } |
| 626 | +}; |
| 627 | + |
| 628 | +struct vf_utf16_charp { |
| 629 | + static String From(napi_env env, const char16_t* value) { |
| 630 | + return String::New(env, value); |
| 631 | + } |
| 632 | +}; |
| 633 | +struct vf_utf8_string { |
| 634 | + static String From(napi_env env, const std::string& value) { |
| 635 | + return String::New(env, value); |
| 636 | + } |
| 637 | +}; |
| 638 | + |
| 639 | +struct vf_utf16_string { |
| 640 | + static String From(napi_env env, const std::u16string& value) { |
| 641 | + return String::New(env, value); |
| 642 | + } |
| 643 | +}; |
| 644 | + |
| 645 | +template <typename T> |
| 646 | +struct vf_fallback { |
| 647 | + static Value From(napi_env env, const T& value) { |
| 648 | + return Value(env, value); |
| 649 | + } |
| 650 | +}; |
| 651 | + |
| 652 | +template <typename...> struct disjunction : std::false_type {}; |
| 653 | +template <typename B> struct disjunction<B> : B {}; |
| 654 | +template <typename B, typename... Bs> |
| 655 | +struct disjunction<B, Bs...> |
| 656 | + : std::conditional<bool(B::value), B, disjunction<Bs...>>::type {}; |
| 657 | + |
| 658 | +template <typename T> |
| 659 | +struct can_make_string |
| 660 | + : disjunction<typename std::is_convertible<T, const char *>::type, |
| 661 | + typename std::is_convertible<T, const char16_t *>::type, |
| 662 | + typename std::is_convertible<T, std::string>::type, |
| 663 | + typename std::is_convertible<T, std::u16string>::type> {}; |
| 664 | +} |
| 665 | + |
| 666 | +template <typename T> |
| 667 | +Value Value::From(napi_env env, const T& value) { |
| 668 | + using Helper = typename std::conditional< |
| 669 | + std::is_integral<T>::value || std::is_floating_point<T>::value, |
| 670 | + details::vf_number<T>, |
| 671 | + typename std::conditional< |
| 672 | + details::can_make_string<T>::value, |
| 673 | + String, |
| 674 | + details::vf_fallback<T> |
| 675 | + >::type |
| 676 | + >::type; |
| 677 | + return Helper::From(env, value); |
| 678 | +} |
| 679 | + |
| 680 | +template <typename T> |
| 681 | +String String::From(napi_env env, const T& value) { |
| 682 | + struct Dummy {}; |
| 683 | + using Helper = typename std::conditional< |
| 684 | + std::is_convertible<T, const char*>::value, |
| 685 | + details::vf_utf8_charp, |
| 686 | + typename std::conditional< |
| 687 | + std::is_convertible<T, const char16_t*>::value, |
| 688 | + details::vf_utf16_charp, |
| 689 | + typename std::conditional< |
| 690 | + std::is_convertible<T, std::string>::value, |
| 691 | + details::vf_utf8_string, |
| 692 | + typename std::conditional< |
| 693 | + std::is_convertible<T, std::u16string>::value, |
| 694 | + details::vf_utf16_string, |
| 695 | + Dummy |
| 696 | + >::type |
| 697 | + >::type |
| 698 | + >::type |
| 699 | + >::type; |
| 700 | + return Helper::From(env, value); |
| 701 | +} |
| 702 | + |
602 | 703 | ////////////////////////////////////////////////////////////////////////////////
|
603 | 704 | // Object class
|
604 | 705 | ////////////////////////////////////////////////////////////////////////////////
|
@@ -705,58 +806,32 @@ inline Value Object::Get(const std::string& utf8name) const {
|
705 | 806 | return Get(utf8name.c_str());
|
706 | 807 | }
|
707 | 808 |
|
708 |
| -inline void Object::Set(napi_value key, napi_value value) { |
709 |
| - napi_status status = napi_set_property(_env, _value, key, value); |
| 809 | +template <typename ValueType> |
| 810 | +inline void Object::Set(napi_value key, const ValueType& value) { |
| 811 | + napi_status status = |
| 812 | + napi_set_property(_env, _value, key, Value::From(_env, value)); |
710 | 813 | NAPI_THROW_IF_FAILED(_env, status);
|
711 | 814 | }
|
712 | 815 |
|
713 |
| -inline void Object::Set(Value key, Value value) { |
714 |
| - napi_status status = napi_set_property(_env, _value, key, value); |
| 816 | +template <typename ValueType> |
| 817 | +inline void Object::Set(Value key, const ValueType& value) { |
| 818 | + napi_status status = |
| 819 | + napi_set_property(_env, _value, key, Value::From(_env, value)); |
715 | 820 | NAPI_THROW_IF_FAILED(_env, status);
|
716 | 821 | }
|
717 | 822 |
|
718 |
| -inline void Object::Set(const char* utf8name, Value value) { |
719 |
| - napi_status status = napi_set_named_property(_env, _value, utf8name, value); |
| 823 | +template <typename ValueType> |
| 824 | +inline void Object::Set(const char* utf8name, const ValueType& value) { |
| 825 | + napi_status status = |
| 826 | + napi_set_named_property(_env, _value, utf8name, Value::From(_env, value)); |
720 | 827 | NAPI_THROW_IF_FAILED(_env, status);
|
721 | 828 | }
|
722 | 829 |
|
723 |
| -inline void Object::Set(const char* utf8name, napi_value value) { |
724 |
| - napi_status status = napi_set_named_property(_env, _value, utf8name, value); |
725 |
| - NAPI_THROW_IF_FAILED(_env, status); |
726 |
| -} |
727 |
| - |
728 |
| -inline void Object::Set(const char* utf8name, const char* utf8value) { |
729 |
| - Set(utf8name, String::New(Env(), utf8value)); |
730 |
| -} |
731 |
| - |
732 |
| -inline void Object::Set(const char* utf8name, bool boolValue) { |
733 |
| - Set(utf8name, Boolean::New(Env(), boolValue)); |
734 |
| -} |
735 |
| - |
736 |
| -inline void Object::Set(const char* utf8name, double numberValue) { |
737 |
| - Set(utf8name, Number::New(Env(), numberValue)); |
738 |
| -} |
739 |
| - |
740 |
| -inline void Object::Set(const std::string& utf8name, napi_value value) { |
741 |
| - Set(utf8name.c_str(), value); |
742 |
| -} |
743 |
| - |
744 |
| -inline void Object::Set(const std::string& utf8name, Value value) { |
| 830 | +template <typename ValueType> |
| 831 | +inline void Object::Set(const std::string& utf8name, const ValueType& value) { |
745 | 832 | Set(utf8name.c_str(), value);
|
746 | 833 | }
|
747 | 834 |
|
748 |
| -inline void Object::Set(const std::string& utf8name, std::string& utf8value) { |
749 |
| - Set(utf8name.c_str(), String::New(Env(), utf8value)); |
750 |
| -} |
751 |
| - |
752 |
| -inline void Object::Set(const std::string& utf8name, bool boolValue) { |
753 |
| - Set(utf8name.c_str(), Boolean::New(Env(), boolValue)); |
754 |
| -} |
755 |
| - |
756 |
| -inline void Object::Set(const std::string& utf8name, double numberValue) { |
757 |
| - Set(utf8name.c_str(), Number::New(Env(), numberValue)); |
758 |
| -} |
759 |
| - |
760 | 835 | inline bool Object::Delete(napi_value key) {
|
761 | 836 | bool result;
|
762 | 837 | napi_status status = napi_delete_property(_env, _value, key, &result);
|
@@ -793,32 +868,13 @@ inline Value Object::Get(uint32_t index) const {
|
793 | 868 | return Value(_env, value);
|
794 | 869 | }
|
795 | 870 |
|
796 |
| -inline void Object::Set(uint32_t index, napi_value value) { |
797 |
| - napi_status status = napi_set_element(_env, _value, index, value); |
| 871 | +template <typename ValueType> |
| 872 | +inline void Object::Set(uint32_t index, const ValueType& value) { |
| 873 | + napi_status status = |
| 874 | + napi_set_element(_env, _value, index, Value::From(_env, value)); |
798 | 875 | NAPI_THROW_IF_FAILED(_env, status);
|
799 | 876 | }
|
800 | 877 |
|
801 |
| -inline void Object::Set(uint32_t index, Value value) { |
802 |
| - napi_status status = napi_set_element(_env, _value, index, value); |
803 |
| - NAPI_THROW_IF_FAILED(_env, status); |
804 |
| -} |
805 |
| - |
806 |
| -inline void Object::Set(uint32_t index, const char* utf8value) { |
807 |
| - Set(index, static_cast<napi_value>(String::New(Env(), utf8value))); |
808 |
| -} |
809 |
| - |
810 |
| -inline void Object::Set(uint32_t index, const std::string& utf8value) { |
811 |
| - Set(index, static_cast<napi_value>(String::New(Env(), utf8value))); |
812 |
| -} |
813 |
| - |
814 |
| -inline void Object::Set(uint32_t index, bool boolValue) { |
815 |
| - Set(index, static_cast<napi_value>(Boolean::New(Env(), boolValue))); |
816 |
| -} |
817 |
| - |
818 |
| -inline void Object::Set(uint32_t index, double numberValue) { |
819 |
| - Set(index, static_cast<napi_value>(Number::New(Env(), numberValue))); |
820 |
| -} |
821 |
| - |
822 | 878 | inline bool Object::Delete(uint32_t index) {
|
823 | 879 | bool result;
|
824 | 880 | napi_status status = napi_delete_element(_env, _value, index, &result);
|
|
0 commit comments