@@ -331,6 +331,13 @@ struct async {
331
331
};
332
332
};
333
333
334
+ struct pure_virtual {
335
+ template <typename InputType, int Index>
336
+ struct Transform {
337
+ typedef InputType type;
338
+ };
339
+ };
340
+
334
341
namespace return_value_policy {
335
342
336
343
struct take_ownership : public allow_raw_pointers {};
@@ -340,6 +347,49 @@ struct reference : public allow_raw_pointers {};
340
347
341
348
namespace internal {
342
349
350
+ template <typename ... Policies>
351
+ struct isPolicy ;
352
+
353
+ template <typename ... Rest>
354
+ struct isPolicy <return_value_policy::take_ownership, Rest...> {
355
+ static constexpr bool value = true ;
356
+ };
357
+
358
+ template <typename ... Rest>
359
+ struct isPolicy <return_value_policy::reference, Rest...> {
360
+ static constexpr bool value = true ;
361
+ };
362
+
363
+ template <typename ... Rest>
364
+ struct isPolicy <emscripten::async, Rest...> {
365
+ static constexpr bool value = true ;
366
+ };
367
+
368
+ template <typename T, typename ... Rest>
369
+ struct isPolicy <emscripten::allow_raw_pointer<T>, Rest...> {
370
+ static constexpr bool value = true ;
371
+ };
372
+
373
+ template <typename ... Rest>
374
+ struct isPolicy <allow_raw_pointers, Rest...> {
375
+ static constexpr bool value = true ;
376
+ };
377
+
378
+ template <typename ... Rest>
379
+ struct isPolicy <emscripten::pure_virtual, Rest...> {
380
+ static constexpr bool value = true ;
381
+ };
382
+
383
+ template <typename T, typename ... Rest>
384
+ struct isPolicy <T, Rest...> {
385
+ static constexpr bool value = isPolicy<Rest...>::value;
386
+ };
387
+
388
+ template <>
389
+ struct isPolicy <> {
390
+ static constexpr bool value = false ;
391
+ };
392
+
343
393
template <typename ReturnType, typename ... Rest>
344
394
struct GetReturnValuePolicy {
345
395
using tag = rvp::default_tag;
@@ -691,12 +741,12 @@ struct MemberAccess {
691
741
typedef internal::BindingType<MemberType> MemberBinding;
692
742
typedef typename MemberBinding::WireType WireType;
693
743
694
- template <typename ClassType>
744
+ template <typename ClassType, typename ReturnPolicy = rvp::default_tag >
695
745
static WireType getWire (
696
746
const MemberPointer& field,
697
- const ClassType& ptr
747
+ ClassType& ptr
698
748
) {
699
- return MemberBinding::toWireType (ptr.*field, rvp::default_tag {});
749
+ return MemberBinding::toWireType (ptr.*field, ReturnPolicy {});
700
750
}
701
751
702
752
template <typename ClassType>
@@ -748,9 +798,9 @@ struct GetterPolicy<GetterReturnType (GetterThisType::*)() const> {
748
798
typedef internal::BindingType<ReturnType> Binding;
749
799
typedef typename Binding::WireType WireType;
750
800
751
- template <typename ClassType>
801
+ template <typename ClassType, typename ReturnPolicy >
752
802
static WireType get (const Context& context, const ClassType& ptr) {
753
- return Binding::toWireType ((ptr.*context)(), rvp::default_tag {});
803
+ return Binding::toWireType ((ptr.*context)(), ReturnPolicy {});
754
804
}
755
805
756
806
static void * getContext (Context context) {
@@ -772,9 +822,9 @@ struct GetterPolicy<GetterReturnType (*)(const GetterThisType&)> {
772
822
typedef internal::BindingType<ReturnType> Binding;
773
823
typedef typename Binding::WireType WireType;
774
824
775
- template <typename ClassType>
825
+ template <typename ClassType, typename ReturnPolicy >
776
826
static WireType get (const Context& context, const ClassType& ptr) {
777
- return Binding::toWireType (context (ptr), rvp::default_tag {});
827
+ return Binding::toWireType (context (ptr), ReturnPolicy {});
778
828
}
779
829
780
830
static void * getContext (Context context) {
@@ -790,9 +840,9 @@ struct GetterPolicy<std::function<GetterReturnType(const GetterThisType&)>> {
790
840
typedef internal::BindingType<ReturnType> Binding;
791
841
typedef typename Binding::WireType WireType;
792
842
793
- template <typename ClassType>
843
+ template <typename ClassType, typename ReturnPolicy >
794
844
static WireType get (const Context& context, const ClassType& ptr) {
795
- return Binding::toWireType (context (ptr), rvp::default_tag {});
845
+ return Binding::toWireType (context (ptr), ReturnPolicy {});
796
846
}
797
847
798
848
static void * getContext (const Context& context) {
@@ -808,9 +858,9 @@ struct GetterPolicy<PropertyTag<Getter, GetterReturnType>> {
808
858
typedef internal::BindingType<ReturnType> Binding;
809
859
typedef typename Binding::WireType WireType;
810
860
811
- template <typename ClassType>
861
+ template <typename ClassType, typename ReturnPolicy >
812
862
static WireType get (const Context& context, const ClassType& ptr) {
813
- return Binding::toWireType (context (ptr), rvp::default_tag {});
863
+ return Binding::toWireType (context (ptr), ReturnPolicy {});
814
864
}
815
865
816
866
static void * getContext (const Context& context) {
@@ -899,6 +949,18 @@ struct SetterPolicy<PropertyTag<Setter, SetterArgumentType>> {
899
949
}
900
950
};
901
951
952
+ // Helper available in C++14.
953
+ template <bool _Test, class _T1 , class _T2 >
954
+ using conditional_t = typename std::conditional<_Test, _T1, _T2>::type;
955
+
956
+ // Conjunction is available in C++17
957
+ template <class ...> struct conjunction : std::true_type {};
958
+ template <class B1 > struct conjunction <B1> : B1 {};
959
+ template <class B1 , class ... Bn>
960
+ struct conjunction <B1, Bn...>
961
+ : conditional_t <bool (B1::value), conjunction<Bn...>, B1> {};
962
+
963
+
902
964
class noncopyable {
903
965
protected:
904
966
noncopyable () {}
@@ -980,7 +1042,7 @@ class value_array : public internal::noncopyable {
980
1042
typedef GetterPolicy<Getter> GP;
981
1043
typedef SetterPolicy<Setter> SP;
982
1044
983
- auto g = &GP::template get<ClassType>;
1045
+ auto g = &GP::template get<ClassType, rvp::default_tag >;
984
1046
auto s = &SP::template set<ClassType>;
985
1047
986
1048
_embind_register_value_array_element (
@@ -1106,7 +1168,7 @@ class value_object : public internal::noncopyable {
1106
1168
typedef GetterPolicy<Getter> GP;
1107
1169
typedef SetterPolicy<Setter> SP;
1108
1170
1109
- auto g = &GP::template get<ClassType>;
1171
+ auto g = &GP::template get<ClassType, rvp::default_tag >;
1110
1172
auto s = &SP::template set<ClassType>;
1111
1173
1112
1174
_embind_register_value_object_field (
@@ -1346,13 +1408,6 @@ val wrapped_extend(const std::string& name, const val& properties) {
1346
1408
1347
1409
} // end namespace internal
1348
1410
1349
- struct pure_virtual {
1350
- template <typename InputType, int Index>
1351
- struct Transform {
1352
- typedef InputType type;
1353
- };
1354
- };
1355
-
1356
1411
namespace internal {
1357
1412
1358
1413
template <typename ... Policies>
@@ -1741,15 +1796,24 @@ class class_ {
1741
1796
return *this ;
1742
1797
}
1743
1798
1744
- template <typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
1745
- EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, const FieldType ClassType::*field) const {
1799
+ template <
1800
+ typename FieldType,
1801
+ typename ... Policies,
1802
+ // Prevent the template from wrongly matching the getter function
1803
+ // overload.
1804
+ typename = typename std::enable_if<
1805
+ !std::is_function<FieldType>::value &&
1806
+ internal::conjunction<internal::isPolicy<Policies>...>::value>::type>
1807
+ EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, const FieldType ClassType::*field, Policies...) const {
1746
1808
using namespace internal ;
1809
+ using ReturnPolicy = GetReturnValuePolicy<FieldType, Policies...>::tag;
1810
+ typename WithPolicies<Policies...>::template ArgTypeList<FieldType> returnType;
1747
1811
1748
- auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType>;
1812
+ auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType, ReturnPolicy >;
1749
1813
_embind_register_class_property (
1750
1814
TypeID<ClassType>::get (),
1751
1815
fieldName,
1752
- TypeID<FieldType>:: get () ,
1816
+ returnType. getTypes ()[ 0 ] ,
1753
1817
getSignature (getter),
1754
1818
reinterpret_cast <GenericFunction>(getter),
1755
1819
getContext (field),
@@ -1760,40 +1824,57 @@ class class_ {
1760
1824
return *this ;
1761
1825
}
1762
1826
1763
- template <typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
1764
- EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, FieldType ClassType::*field) const {
1827
+ template <
1828
+ typename FieldType,
1829
+ typename ... Policies,
1830
+ // Prevent the template from wrongly matching the getter function
1831
+ // overload.
1832
+ typename = typename std::enable_if<
1833
+ !std::is_function<FieldType>::value &&
1834
+ internal::conjunction<internal::isPolicy<Policies>...>::value>::type>
1835
+ EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, FieldType ClassType::*field, Policies...) const {
1765
1836
using namespace internal ;
1837
+ using ReturnPolicy = GetReturnValuePolicy<FieldType, Policies...>::tag;
1838
+ typename WithPolicies<Policies...>::template ArgTypeList<FieldType> returnType;
1766
1839
1767
- auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType>;
1840
+ auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType, ReturnPolicy >;
1768
1841
auto setter = &MemberAccess<ClassType, FieldType>::template setWire<ClassType>;
1769
1842
_embind_register_class_property (
1770
1843
TypeID<ClassType>::get (),
1771
1844
fieldName,
1772
- TypeID<FieldType>:: get () ,
1845
+ returnType. getTypes ()[ 0 ] ,
1773
1846
getSignature (getter),
1774
1847
reinterpret_cast <GenericFunction>(getter),
1775
1848
getContext (field),
1776
- TypeID<FieldType>:: get () ,
1849
+ returnType. getTypes ()[ 0 ] ,
1777
1850
getSignature (setter),
1778
1851
reinterpret_cast <GenericFunction>(setter),
1779
1852
getContext (field));
1780
1853
return *this ;
1781
1854
}
1782
1855
1783
- template <typename PropertyType = internal::DeduceArgumentsTag, typename Getter>
1784
- EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, Getter getter) const {
1856
+ template <
1857
+ typename PropertyType = internal::DeduceArgumentsTag,
1858
+ typename Getter,
1859
+ typename ... Policies,
1860
+ // Prevent the template from wrongly matching the getter/setter overload
1861
+ // of this function.
1862
+ typename = typename std::enable_if<
1863
+ internal::conjunction<internal::isPolicy<Policies>...>::value>::type>
1864
+ EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, Getter getter, Policies...) const {
1785
1865
using namespace internal ;
1786
1866
1787
1867
typedef GetterPolicy<
1788
1868
typename std::conditional<std::is_same<PropertyType, internal::DeduceArgumentsTag>::value,
1789
1869
Getter,
1790
1870
PropertyTag<Getter, PropertyType>>::type> GP;
1791
-
1792
- auto gter = &GP::template get<ClassType>;
1871
+ using ReturnPolicy = GetReturnValuePolicy<typename GP::ReturnType, Policies...>::tag;
1872
+ auto gter = &GP::template get<ClassType, ReturnPolicy>;
1873
+ typename WithPolicies<Policies...>::template ArgTypeList<typename GP::ReturnType> returnType;
1793
1874
_embind_register_class_property (
1794
1875
TypeID<ClassType>::get (),
1795
1876
fieldName,
1796
- TypeID< typename GP::ReturnType>:: get () ,
1877
+ returnType. getTypes ()[ 0 ] ,
1797
1878
getSignature (gter),
1798
1879
reinterpret_cast <GenericFunction>(gter),
1799
1880
GP::getContext (getter),
@@ -1804,9 +1885,18 @@ class class_ {
1804
1885
return *this ;
1805
1886
}
1806
1887
1807
- template <typename PropertyType = internal::DeduceArgumentsTag, typename Getter, typename Setter>
1808
- EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, Getter getter, Setter setter) const {
1888
+ template <
1889
+ typename PropertyType = internal::DeduceArgumentsTag,
1890
+ typename Getter,
1891
+ typename Setter,
1892
+ typename ... Policies,
1893
+ // Similar to the other variadic property overloads this can greedily
1894
+ // match the wrong overload so we need to ensure the setter is not a
1895
+ // policy argument.
1896
+ typename = typename std::enable_if<!internal::isPolicy<Setter>::value>::type>
1897
+ EMSCRIPTEN_ALWAYS_INLINE const class_& property (const char * fieldName, Getter getter, Setter setter, Policies...) const {
1809
1898
using namespace internal ;
1899
+ using ReturnPolicy = GetReturnValuePolicy<PropertyType, Policies...>::tag;
1810
1900
1811
1901
typedef GetterPolicy<
1812
1902
typename std::conditional<std::is_same<PropertyType, internal::DeduceArgumentsTag>::value,
@@ -1818,7 +1908,7 @@ class class_ {
1818
1908
PropertyTag<Setter, PropertyType>>::type> SP;
1819
1909
1820
1910
1821
- auto gter = &GP::template get<ClassType>;
1911
+ auto gter = &GP::template get<ClassType, ReturnPolicy >;
1822
1912
auto ster = &SP::template set<ClassType>;
1823
1913
1824
1914
_embind_register_class_property (
0 commit comments